pthread_join()和pthread_exit()

43

我有一个关于C并发编程的问题。

在pthread库中,pthread_join的原型是:

int pthread_join(pthread_t tid, void **ret);

pthread_exit 的原型是:

void pthread_exit(void *ret);

我有点困惑,为什么pthread_join从回收的线程中获取进程的返回值时需要使用指向void指针的指针,而pthread_exit只需要使用指向void的指针作为退出的线程的返回值呢?我的意思是它们基本上都是线程的返回值,为什么类型会有差异?

3个回答

40
pthread_exit中,ret是一个输入参数。你只需将变量的地址传递给函数。
pthread_join中,ret是一个输出参数。你从函数中得到一个值。这个值可以设置为NULL等。
长话短说:
pthread_join中,你会得到由完成线程通过pthread_exit传递的地址。如果你只传递一个普通指针,它是按值传递的,因此你无法更改它所指向的位置。为了能够更改传递给pthread_join的指针的值,必须将其作为指针本身传递,也就是指向指针的指针。

但为什么在pthread_exit中定义ret为void *类型,它总是为空或一些其他常量值? - stonestrong

32

这是因为每一次

void pthread_exit(void *ret);

将被从线程函数中调用,所以无论您想返回什么,只需使用pthread_exit()传递其指针即可。

现在在

int pthread_join(pthread_t tid, void **ret);

这个函数将始终从创建线程的位置调用,因此在接受返回的指针时,你需要使用双重指针

我认为以下代码可以帮助你理解这个问题。

#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>

void* thread_function(void *ignoredInThisExample)
{
    char *a = malloc(10);
    strcpy(a,"hello world");
    pthread_exit((void*)a);
}
int main()
{
    pthread_t thread_id;
    char *b;

    pthread_create (&thread_id, NULL,&thread_function, NULL);

    pthread_join(thread_id,(void**)&b); //here we are reciving one pointer 
                                        value so to use that we need double pointer 
    printf("b is %s\n",b); 
    free(b); // lets free the memory

}

如果在main()中分配了a到堆上,那么为什么必须释放b?这是为什么? - M. Smith

2
典型的用法是:
void* ret = NULL;
pthread_t tid = something; /// change it suitably
if (pthread_join (tid, &ret)) 
   handle_error();
// do something with the return value ret

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接