Linux如何返回線程退出時的數據(以整數為例)


在Linux中,線程的應用還是比較廣泛的,同時,線程退出的返回值對線程來說,也是一種比較客觀的數據傳輸。

本文主要是在Linux中進行測試,不涉及windows等其他OS。

1. 線程的創建

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

首先,參數一:代表的是線程的pid地址

      參數二:代表的是是否設置線程的分離屬性,這里設置為NULL,不分離

      參數三:代表的是線程的處理函數

      參數四:線程處理函數的參數列表,這里設置為NULL,不帶參數內容

     (注意,這里主要是創建線程的作用)

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)是沒有辦法進行交換的,所以,如果我

         們需要修改傳過來的參數的話,必須是要使用這個參數的地址,或者是一個變量本身是不變的內存地址空間,這樣才可以進行修改,否則,

         修改失敗或者返回值是隨機值。

 

    結果:

              

 

 

      上述的結果表明,返回的數值是我們所要求的數值,是正確的。讀者可以試着返回的是一個字符串,這樣就比返回是一個整數

     更加簡單明了。說到底,整篇文章也就是強制轉換的結果。讀者可以更加深入地自己去理解

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM