在Linux中,線程的應用仍是比較普遍的,同時,線程退出的返回值對線程來講,也是一種比較客觀的數據傳輸。windows
本文主要是在Linux中進行測試,不涉及windows等其餘OS。函數
1. 線程的建立測試
pthread_create(pthread_t *thread,const pthread_attr_t *attr,void*(*start_routine)(void*),void* arg);spa
首先,參數一:表明的是線程的pid地址線程
參數二:表明的是是否設置線程的分離屬性,這裏設置爲NULL,不分離設計
參數三:表明的是線程的處理函數指針
參數四:線程處理函數的參數列表,這裏設置爲NULL,不帶參數內容code
(注意,這裏主要是建立線程的做用)
blog
2. 線程的等待內存
pthread_join(pthread_t thread, void **retval)
首先: 參數一: 表明線程pid
參數二: 表明線程的返回值 (--> 這個是本文討論的重點參數)
3. 例子設計:
這裏設計兩個線程,線程一是經過通常的return返回,做爲線程的返回值;線程二,則是使用線程庫中的pthread_exit()函數
來進行返回參數。
首先,函數pthread_exit(void *retval)
這裏的retval就是線程退出的時候返回給主線程的值,也是今天須要討論的狀況。
例子以下:
1 #include <pthread.h> 2 #include <stdio.h> 3 #include <string.h> 4 #include <unistd.h> 5 #include <errno.h> 6 7 #define PTHREAD_NUM 2 8 9 void *sendData(void *arg) 10 { 11 static int count = 2; 12 13 pthread_exit((void*)(&count)); 14 15 } 16 17 18 void *recvData(void *arg) 19 { 20 static int count = 3; 21 22 return (void *)(&count); 23 24 25 } 26 27 28 int main(int argc,char *argv[]) 29 { 30 pthread_t pid[PTHREAD_NUM]; 31 int retPid; 32 int *ret; 33 int *dat; 34 35 36 if((retPid = pthread_create(&pid[0],NULL,sendData,NULL)) != 0) 37 { 38 perror("create pid first failed"); 39 return -1; 40 } 41 42 43 if((retPid = pthread_create(&pid[1],NULL,recvData,NULL)) != 0) 44 { 45 perror("create pid second failed"); 46 return -1; 47 } 48 49 50 if(pid[0] != 0) 51 { 52 53 pthread_join(pid[0],(void**)&ret); 54 printf("get thread 0 message: %d\n",*ret); 55 } 56 57 58 if(pid[1] != 0) 59 { 60 pthread_join(pid[1],(void**)&dat); 61 printf("get thread 1 message: %d\n",*dat); 62 } 63 64 65 return 0; 66 }
講解:這裏的最主要的問題就是咱們須要進行強制類型的轉換。
首先,對於pthread_exit這個函數,他的返回參數的類型爲void *,如今咱們返回的是一個「整數」,所以必須將其進行轉換
1. 先轉換爲整形指針,count爲int類型,那麼&count爲int*類型,一樣爲了保持匹配,這裏本人使用顯式的調用,直接寫做爲
&count,其實這個代表瞭如今變成了一個int的指針,這個時候與void*匹配的話,須要進行強制轉換,也就是代碼中的
(void*)(&count);
2. return這個關鍵字進行返回值得時候,一樣也是須要進行強制類型的轉換。線程函數的返回類型是void*,那麼對於count這個
整形數值來講,必須進行轉換爲void的指針類型(即void*),所以有:(void*)((int*)&count);
3. 對於接收返回值的線程函數pthread_join來講,有兩個做用。其一就是等待線程結束,其二就是獲取線程結束的時候返回的數值
是什麼。因此,對於它的參數類型是void**這種二級指針的,咱們能夠把它分解爲一級指針,這樣就比較容易進行理解和調用。本文
討論的是整數,那麼設置接收返回值得爲一個整形指針,這樣就感受給二級指針void**降階了。
4. 對接收返回值得參數進行強制轉換,這裏定義接收返回值得類型是int*,所以轉化爲void**,也就是(void**)&ret,由於&ret就已
經說明了如今的類型爲int**,而後顯式地轉爲void**便可
5. 另外,本文在返回整數數值的時候使用到了static這個關鍵字,這是由於必須肯定返回值的地址是不變的。對於count變量而言,在
內存上來說,屬於在棧區開闢的變量,那麼在調用結束的時候,必然是釋放內存空間的,相對而言,這時候,就沒辦法找到count所表明
內容的地址空間。這就是爲何不少人在看到swap交換函數的時候,爲何寫成swap(int,int)是沒有辦法進行交換的,因此,若是我
們須要修改傳過來的參數的話,必須是要使用這個參數的地址,或者是一個變量自己是不變的內存地址空間,這樣才能夠進行修改,不然,
修改失敗或者返回值是隨機值。
結果:
上述的結果代表,返回的數值是咱們所要求的數值,是正確的。讀者能夠試着返回的是一個字符串,這樣就比返回是一個整數
更加簡單明瞭。說到底,整篇文章也就是強制轉換的結果。讀者能夠更加深刻地本身去理解