用C语言创建线程

用C语言创建线程,c,pthreads,C,Pthreads,我真的不明白pthread_create中void*的需求是什么。我们是否需要在同一个世界中打印\u hello\u world,或者可以删除——————————————————&mdas void print_hello_world() { pid_t pid = getp

我真的不明白pthread_create中void*的需求是什么。我们是否需要在同一个世界中打印\u hello\u world,或者可以删除——————————————————&mdas

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*作为参数,并返回void*。因此,您的功能应该是:

pthread_create(&thread, NULL, print_hello_world, NULL);
这是实现泛型数据类型的C方式。例如,您可以将int*或struct args*传递给线程函数并将其检索回来。 例如

在函数print_hello_world中,您可以执行以下操作:

 int i=5;
 pthread_create(&thread, NULL, print_hello_world, &i); 
基本上,void*允许您在此处向线程函数传递任何数据指针。例如,如果pthread_create的线程函数采用int*,则无法将结构args*传递给它

我建议您阅读以下文章,了解有关void指针及其在C中的用法的更多信息:


是的,不需要强制转换或&operator:

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*作为参数,并返回void*。因此,您的功能应该是:

pthread_create(&thread, NULL, print_hello_world, NULL);
这是实现泛型数据类型的C方式。例如,您可以将int*或struct args*传递给线程函数并将其检索回来。 例如

在函数print_hello_world中,您可以执行以下操作:

 int i=5;
 pthread_create(&thread, NULL, print_hello_world, &i); 
基本上,void*允许您在此处向线程函数传递任何数据指针。例如,如果pthread_create的线程函数采用int*,则无法将结构args*传递给它

我建议您阅读以下文章,了解有关void指针及其在C中的用法的更多信息:


从void*强制转换函数指针实际上是未定义的行为。请参阅,尤其是p1和p8。请注意,函数在C中是不可用的

因此,演员阵容实际上是错误的,操作员的地址&是不必要的。但是,您可以将一个函数指针强制转换为另一个函数指针,请参见参考资料的§8。但是在这里,您应该为您的函数确定一个合适的签名,因为它接受指针并返回指针也是有原因的。因此:不要强制转换,但要获得正确的签名和语义


注意:作为定义一部分的函数声明中的空标识符列表为空标识符列表。建议对空参数列表使用原型样式void。此外,就上述内容而言,int mainvoid所需的最小签名。

从void*转换函数指针实际上是未定义的行为。请参阅,尤其是p1和p8。请注意,函数在C中是不可用的

因此,演员阵容实际上是错误的,操作员的地址&是不必要的。但是,您可以将一个函数指针强制转换为另一个函数指针,请参见参考资料的§8。但是在这里,您应该为您的函数确定一个合适的签名,因为它接受指针并返回指针也是有原因的。因此:不要强制转换,但要获得正确的签名和语义


注意:作为定义一部分的函数声明中的空标识符列表为空标识符列表。建议对空参数列表使用原型样式void。此外,就上述内容而言,int mainvoid所需的最低签名是无效的。

无效*可能意味着什么?int*表示返回值是一个整数指针。无效指针没有意义:/你能详细说明一下吗?我不能understand@UtkarshGupta评论太大了。请查看更新后的答案。如果是这样,我们不能将传递的参数从int*转换为struct*吗?或者反之亦然?@UtkarshGupta将TYPE1*转换为TYPE2*不能保证适用于除转换为字符类型:char*、unsigned char*或signed char*之外的所有类型。使用void*是唯一不用担心别名的可移植方法。void*可能意味着什么?int*表示返回值是一个整数指针。无效指针没有意义:/你能详细说明一下吗?我不能understand@UtkarshGupta评论太大了。请查看更新后的答案。如果是这样,我们不能将传递的参数从int*转换为struct*吗?或者反之亦然?@UtkarshGupta将TYPE1*转换为TYPE2*不能保证适用于除转换为字符类型:char*、unsigned char*或signed char*之外的所有类型。使用void*是唯一一种不必担心别名的可移植方法。您能否引用一句话,说明一个没有参数的函数必须声明为[type]foovid?另外,真正的问题是pthread_create需要一个指向void**void*@EOF类型函数的指针:对于vs.void,我有点过分;这只会在未来版本中变得过时
充分地我相应地编辑了我的文本。关于函数指针:实际上已经涵盖了它。哦,等等,我刚注意到你的意思。已编辑。您是否可以引用一个声明,即不带参数的函数必须声明为[type]foovoid?另外,真正的问题是pthread_create需要一个指向void**void*@EOF类型函数的指针:对于vs.void,我有点过分;这只是希望在未来的版本中过时;我相应地编辑了我的文本。关于函数指针:实际上已经涵盖了它。哦,等等,我刚注意到你的意思。编辑。