#c #multithreading #pointers #pthreads #function-pointers
#c #многопоточность #указатели #pthreads #функции-указатели
Вопрос:
У меня вопрос: каков именно формат функции pthread_create и функции, которую она вызывает, с точки зрения указателей и тому подобного? Я могу разобраться с указателями на переменные, хотя мне нужно уточнить свои знания в этой области, но указатели на функции становятся неприглядными.
Я понимаю, что предпочтительный формат
void *threadfunc(void *arg);
int main()
{
pthread_t threadinfo;
int samplearg;
pthread_create(amp;threadinfo, NULL, threadfunc, amp;samplearg);
}
Однако это генерирует предупреждение компилятора о том, что threadfunc не возвращает значение, поэтому, по-видимому, * — это что-то о том, что возвращает threadfunc, а не характеристика функции?
Я также видел функцию, определенную как и pthread_create , отформатированную следующим образом:
void threadfunc(void *arg);
pthread_create(amp;threadinfo, NULL, (void *)threadfunc, amp;samplearg);
Какие из этих двух правильны или они функционально эквивалентны? Может ли кто-нибудь объяснить мне механику указателей на функции и тому подобное?
И последний вопрос: будет ли работать внутри цикла for, генерирующего несколько потоков, инициализировать int samplearg
уникальные значения for thread, а затем передать их pthread_create(...)
? Я понимаю samplearg
, что это было бы в области видимости внутри threadfunc
, я просто проверяю, не соответствует ли C типичным правилам области видимости — поскольку samplearg
создается внутри for()
цикла и обычно выходит из области видимости после итерации for()
цикла, а сама фактическая переменная передается, а не значение. Я бы проверил себя, но, возможно, вы могли бы просветить меня, и разработка на удаленной машине Linux для меня немного громоздка.
Комментарии:
1. pthread_create( ) возвращает значение int. С справочной страницы: ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ В случае успеха функция pthread_create() должна вернуть ноль; в противном случае должен быть возвращен номер ошибки, указывающий на ошибку.
2. @PeteWilson — он не говорит о возвращаемом значении
pthread_create()
3. @Брайан Роуч — значит, это не так! спасибо за ответ.
Ответ №1:
Вы не предоставили свою версию void *threadfunc(void *arg);
, но я предполагаю, что в ней нет инструкции return. Вот почему компилятор предупреждает вас. Поскольку в объявлении указано , что оно должно возвращать a void*
, вы должны вернуть a void*
. A void*
— это указатель на любой тип указателя. Only void
(без звезды) не нуждается в операторе return, потому что он ничего не возвращает.
Кстати, возвращаемое значение будет передано pthread_join
оператору, когда другой поток присоединится к потоку, который вы запускаете в данный момент.
Комментарии:
1. Да, у меня не было возвращаемого значения, так как я неправильно
void *threadfunc(void *arg);
понял, что это функция с пустым возвращаемым значением и специальным свойством, указанным*
. Какой была бы подходящая «заготовка»return
? Или это должноreturn
быть что-то другое? Конечноpthread_exit()
, это было бы вызвано само поthreadfunc()
себе.2. Если нет ничего, что вы хотели бы вернуть в присоединяющийся поток, просто верните NULL .
3. Я думаю, что теперь я понял цель указателя на void return — передать переменную, которая затем будет приведена, аналогично тому, как передается входной аргумент, верно?
Ответ №2:
Перейдите к «источнику» — стандарту POSIX. Ибо pthread_create()
, говорится в нем:
int pthread_create(pthread_t *restrict thread,
const pthread_attr_t *restrict attr,
void *(*start_routine)(void*), void *restrict arg);
То есть ваша «процедура запуска» должна быть функцией, которая возвращает a void *
и которая принимает void *
аргумент.
void *possible_thread_start_routine(void *data)
{
SomeStruct *info = data;
...main code for thread...
return 0;
}
Аргумент , передаваемый процедуре запуска потока , является аргументом , указанным в arg
to pthread_create()
.
Комментарии:
1. Что указывает указатель внутри круглых скобок
start_routine
? Т.е.(*start_routine)
Ответ №3:
Переданная функция pthread_create()
должна возвращать указатель void, который указывает на статус завершения потока.
Это возвращаемое значение доступно вам при вызове pthread_join()
потока после его завершения (либо путем возврата, либо явного вызова pthread_exit()
)
Комментарии:
1. Итак, вы говорите, что первая формулировка с определением функции
void *threadfunc(void *arg);
верна? Какова цель возврата указателя на void? Возможность повторного ввода функции с указателем, полученным изpthread_join()
?