pthread_join的第二个参数

pthread_join的第二个参数

在看pthread相关,遇到了pthread_join函数

#include <pthread.h>
int pthread_join(pthread_t pthread_id, void** retval);

这个函数的第二个参数为什么是void**?有啥用?

首先,这个函数的用途是什么? manpage给出的解释:

      The pthread_join() function waits for the thread specified by thread
       to terminate.  If that thread has already terminated, then
       pthread_join() returns immediately.  The thread specified by thread
       must be joinable.

       If retval is not NULL, then pthread_join() copies the exit status of
       the target thread (i.e., the value that the target thread supplied to
       pthread_exit(3)) into the location pointed to by retval.  If the
       target thread was canceled, then PTHREAD_CANCELED is placed in the
       location pointed to by retval.

       If multiple threads simultaneously try to join with the same thread,
       the results are undefined.  If the thread calling pthread_join() is
       canceled, then the target thread will remain joinable (i.e., it will
       not be detached).

意图很明显,以阻塞的方式等待指定线程(可joinable)结束。成功返回0,失败返回错误号。

一个线程的结束,有两种方式,一种是正常结束。一种是使用pthread_exit。对于使用pthread_exit结束的线程,可以返回一个"status"给主线程。

void pthread_exit(void* retval);

那么它的参数就和pthread_join第二个参数就对应上了。看一下怎么用!

//错误演示
#include <error.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

#include <pthread.h>

struct my_threadfunc_error
{
    int a;
    int b;
};

void* StartFunction(void* arg)
{
    my_threadfunc_error var{1,2};
    pthread_exit((void*)&var);
    return NULL;
}

int main(int argc, char* argv[])
{
    pthread_t my_pthread_t = 0;
    if (0 != pthread_create(&my_pthread_t, NULL, StartFunction, NULL))
    {
        printf("pthread_create error!\n");
        return -1;
    }
    void** p = NULL;
    if (0 != pthread_join(my_pthread_t, p))
    {
        printf("pthread_join error!\n");
        return -1;
    }
    my_threadfunc_error* var = (my_threadfunc_error*)(*p);//11
    printf("var.a = %d, var.b = %d\n", var->a, var->b);
    return 0;
}

上面代码在线程函数中返回的是一个栈上的变量的地址,所在在代码运行到my_threadfunc_error* var = (my_threadfunc_error*)(*p);//11的时候,就出现段错误了。很好理解,因为线程函数结束,线程的栈也会被回收,var的空间也被清理了,所以使用未知的内存发生段错误正常。

既然如此,那么使用malloc或者全局变量即可处理这种问题!

#include <error.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

#include <pthread.h>

struct my_threadfunc_error
{
    int a;
    int b;
};

void* StartFunction(void* arg)
{
    my_threadfunc_error* var = (my_threadfunc_error*)malloc(sizeof(my_threadfunc_error));
    var->a = 100;
    var->b = 200;
    pthread_exit((void*)var);
    return NULL;
}

int main(int argc, char* argv[])
{
    pthread_t my_pthread_t = 0;
    if (0 != pthread_create(&my_pthread_t, NULL, StartFunction, NULL))
    {
        printf("pthread_create error!\n");
        return -1;
    }
    void* p = NULL;
    if (0 != pthread_join(my_pthread_t, &p))
    {
        printf("pthread_join error!\n");
        return -1;
    }
    my_threadfunc_error* var = (my_threadfunc_error*)(p);
    printf("var.a = %d, var.b = %d\n", var->a, var->b);
    free(var);
    return 0;
}

一般来说,pthread_exit返回的是一种状态,一般是一个数字,类似

//do something
pthread_exit(10);

那么如何获取这个返回的状态

#include <error.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

#include <pthread.h>


void* StartFunction(void* arg)
{
    int a =10;
    pthread_exit((void*)a);
    return NULL;
}

int main(int argc, char* argv[])
{
    pthread_t my_pthread_t = 0;
    if (0 != pthread_create(&my_pthread_t, NULL, StartFunction, NULL))
    {
        printf("pthread_create error!\n");
        return -1;
    }
    void* p = NULL;
    if (0 != pthread_join(my_pthread_t, &p))
    {
        printf("pthread_join error!\n");
        return -1;
    }
    printf("ret = %d\n", p);
    return 0;
}
发布了78 篇原创文章 · 获赞 16 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/zeqi1991/article/details/96642285
今日推荐