分析之前先搞明白,這個二級指針其實在函數內部是承接了上個線程的返回值。
看man手冊,發現返回值是個普通指針。人家用二級指針來承接,可能准備干大事。這個可以自己搜索一下。原因嘛,二級指針是保存了這個地址。一級指針承接的話就是這個地址。
那既然二級指針保存了,我們如何訪問那?開始我覺得直接來個二級指針,然后*訪問算了,但是下面的東西。讓你不能那么干了!其實非要那樣也可以 malloc唄!
線程創建函數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是一個野指針!
注意啊!你返回的是一個一級指針,那么存儲就只能是用 * &ret 來存儲(希望你懂,就是指針降級)=ret;
那么輸出自然也就是 ret了。
下面是一個例子:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#define N 64
int a = 10;
void * handler(void *arg)
{
printf("a=%d, %s\n", a, (char *)arg);
strcat((char *)arg, " ......");
pthread_exit(arg);
}
int main()
{
pthread_t tid;
char buf[N] = {"welcome"};
void *result;
if (pthread_create(&tid, NULL, handler, (void *)buf) != 0)
exit(-1);
printf("*\n");
pthread_join(tid, &result);
printf("ret:%s\n", (char *)result);
return 0;
}
