对线程等待函数pthread_join的理解1

线程创建函数pthread_create的函数原型如下:

int pthread_create(pthread_t *restrict thread,
              const pthread_attr_t *restrict attr,
              void *(*start_routine)(void*), void *restrict arg);

其中,thread是要创建的线程;

         attr指定线程的属性,缺省值为NULL;

          start_routine是线程要执行的函数;

          arg是传递给线程执行的函数的参数;

要注意的是:start_routine是函数指针

线程等待函数pthread_create的函数原型如下:

int pthread_join(pthread_t thread, void **value_ptr);

其中,thread是要等待的线程名;

         value_ptr:指针*value_ptr指向线程返回的参数

在使用时要注意的是:针对value_ptr,应该先声明一个一级指针,然后通过取地址的方式传给pthread_create函数,而不应该直接定义一个二级指针,将这个二级指针直接传递给pthread_create。

如:

正确的传递方法:

void *ret;

pthread_join(thread, &ret);

错误的传递方法:

void **ret;

pthread_join(thread, ret);

原因:pthread_join中有一句类型这样的语句:(* value_ptr) = arg;如果按照正确的方式传递参数,左边的语句实际上完成的操作是:ret = arg;一点问题没有。但是,当按照错误的方式传递参数时,会出现一句致命的错误:(* value_ptr),它对一个还没有初始化的指针进行了取值操作,这是系统所不允许的,此时(* value_ptr)等价于*ret,*ret还是一个指针,是一个二级指针,但是*ret是一个野指针!

下面是一个例子:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <unistd.h>
 4 #include <pthread.h>
 5 #include <string.h>
 6 
 7 #define N 64
 8 
 9 int a  = 10;
10 void * handler(void *arg)
11 {
12     printf("a=%d, %s\n", a, (char *)arg);  
13     strcat((char *)arg, "  ......");
14     pthread_exit(arg);   
15 }
16 
17 int main()
18 {
19     pthread_t tid;
20     char buf[N] = {"welcome"};
21     void *result;
22 
23     if (pthread_create(&tid, NULL, handler, (void *)buf) != 0)
24         exit(-1);
25     printf("*\n");
26     pthread_join(tid, &result);
27     printf("ret:%s\n", (char *)result);
28     
29     return 0;
30 }
View Code

image

原文地址:https://www.cnblogs.com/pengdonglin137/p/2945412.html