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();
}
我真的无法理解pthread_create中(void *)的需要。我们需要"& print_hello_world"在相同或可能下降"&"正如我在某处读到的那样,在传递功能指针时,我们不需要放置"&"在函数名之前。
答案 0 :(得分:3)
是的,那里不需要演员或&
运算符:
pthread_create(&thread, NULL, print_hello_world, NULL);
应该足够,因为函数名称在作为参数传递给函数时被转换为函数指针。
请注意,传递给pthread_create()
的函数指针将void*
作为参数并返回void *
。所以你的功能应该是:
void* print_hello_world(void *unused) {
...
}
这是实现“通用”数据类型的C方式。例如,您可以将int*
或struct args*
传递给线程函数并将其检索回来。
E.g。
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*
传递给它。例如。
我建议您阅读以下帖子,了解有关void指针及其在C:
中的用法的更多信息Concept of void pointer in C programming 和 What does void* mean and how to use it?
答案 1 :(得分:2)
向/ void *
转换函数指针实际上是未定义的行为。见6.3.2.3,尤其是p1和p8。请注意,C中的函数不是objects。
所以演员阵容实际上是错误的,并且地址操作符&
是不必要的。但是,您可以将一个函数指针强制转换为另一个函数(参见参考文献的第8节)。但是在这里,你肯定会为你的函数设置一个合适的签名,因为它有一个理由它需要一个指针并返回一个。所以:不要强制转换,但要使签名(和语义)正确。
注意:作为定义的一部分的函数声明中的空标识符列表是obsolescent feature。建议使用原型样式(void)
作为空参数列表。 main
的最低要求签名也是int main(void)
(就上述说法而言)。