2015-08-04 3 views
1
void print_hello_world() { 
    pid_t pid = getpid(); 
    printf("Hello world %d\n", pid); 
    pthread_exit(0); 
} 

void main() { 
    pthread_t thread; 
    pthread_create(&thread, NULL, (void *) &print_hello_world, NULL); 
    print_hello_world(); 
} 

Я действительно не мог понять, в чем заключается необходимость (void *) в pthread_create. И нужно ли нам «& print_hello_world» в том же или может отбросить «&», как я где-то читал, что при передаче указателей функций нам не нужно помещать «&» перед именем функции.Создание потоков в C

ответ

3

Да, нет никакой необходимости в гипсе или & оператора там:

pthread_create(&thread, NULL, print_hello_world, NULL); 

должно хватить как имя функции преобразуется в указатель на функцию при передаче в качестве аргумента функции (ов).

Обратите внимание, что указатель функции, который вы передаете на pthread_create(), принимает в качестве аргумента void* и возвращает void *. Так что ваша функция должна быть:

void* print_hello_world(void *unused) { 
... 
} 

Это C способ реализации «общий» тип данных. Например, вы можете передать int* или struct args* функции потока и вернуть ее обратно. .

int i=5; 
pthread_create(&thread, NULL, print_hello_world, &i); 

и в функции print_hello_world(), вы могли бы сделать:

void *print_hello_world(void *value) { 
    int i = *(int*)value; 
    ... 
} 

В основном void* позволяет передавать любой указатель данных в функцию потока здесь. Если бы функция pthread_create() в потоке принимала int*, вы не смогли бы передать ей struct args*.

Я предлагаю вам прочитать следующие сообщения для получения дополнительной информации о пустом указателе и его использование в C:

Concept of void pointer in C programming и What does void* mean and how to use it?

+0

Что может быть недействительным * возможно? Поскольку int * означает, что возвращаемое значение является целым указателем. Указатель void не имеет смысла. :/ – Utkarsh

+0

Не могли бы вы рассказать? Я не мог понять – Utkarsh

+0

@UtkarshGupta Комментарий становился слишком большим. См. Обновленный ответ. –

2

Кастинг указателя на функцию/из void * фактически неопределенного поведения , См. 6.3.2.3, особенно p1 и p8. Обратите внимание, что функции не являются objects в C.

Так что отливка неправа на самом деле, и адрес-оператор & не нужен. Однако вы можете использовать один указатель на другую (см. §8 справки). Но здесь у вас окончательно есть правильная подпись для вашей функции, так как есть причина, по которой он принимает указатель и возвращает его тоже. Итак: не произносите, но получите правильную подпись (и семантику).

Примечание: пустой идентификатор-лист в функции декларации, которая является частью определения является obsolescent feature. Рекомендуется использовать прототип-стиль (void) для пустого списка аргументов. Также минимальная требуемая подпись для main - int main(void) (в отношении вышеприведенного).

+1

Не могли бы вы привести цитату из утверждения о том, что функция без аргументов должна быть объявлена ​​'[type] foo (void)'? Кроме того, реальная проблема заключается в том, что 'pthread_create()' ожидает указатель на функцию с типом 'void * (*) (void *)'. – EOF

+0

@EOF: Для '()' vs. '(void)' Я был немного завышенным; это просто устаревать в будущей версии (надеюсь); Я отредактировал свой текст соответствующим образом. Относительно указателя на функцию: [6.3.2.3§8] (http://port70.net/~nsz/c/c11/n1570.html#6.3.2.3p8) на самом деле это уже распространяется. Подожди, я просто заметил, что ты имеешь в виду. Ред. – Olaf

Смежные вопросы