формат функции pthread_create и указатели — библиотека C Linux POSIX

#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() ?