1. 程式人生 > >Linux:結束執行緒的三種方式

Linux:結束執行緒的三種方式

轉載: https://www.cnblogs.com/love-DanDan/p/8724241.html

一般情況下,執行緒終止後,其終止狀態一直保留到其它執行緒呼叫pthread_join獲取它的狀態為止。但是執行緒也可以被置為detach狀態,這樣的執行緒一旦終止就立刻回收它佔用的所有資源,而不保留終止狀態。不能對一個已經處於detach狀態的執行緒呼叫pthread_join,這樣的呼叫將返回EINVAL錯誤。也就是說,如果已經對一個執行緒呼叫了pthread_detach就不能再呼叫pthread_join了。

pthread_cancel函式

殺死(取消)執行緒            其作用,對應程序中 kill() 函式。

    int pthread_cancel(pthread_t thread);    成功:0;失敗:錯誤號

    【注意】:執行緒的取消並不是實時的,而有一定的延時。需要等待執行緒到達某個取消點(檢查點)。

    類似於玩遊戲存檔,必須到達指定的場所(存檔點,如:客棧、倉庫、城裡等)才能儲存進度。殺死執行緒也不是立刻就能完成,必須要到達取消點。

    取消點:是執行緒檢查是否被取消,並按請求進行動作的一個位置。通常是一些系統呼叫creat,open,pause,close,read,write..... 執行命令man 7 pthreads可以檢視具備這些取消點的系統呼叫列表。也可參閱 APUE.12.7 取消選項小節。

可粗略認為一個系統呼叫(進入核心)即為一個取消點。如執行緒中沒有取消點,可以通過呼叫pthread_testcancel()函式自行設定一個取消點。

被取消的執行緒,    退出值定義在Linux的pthread庫中。常數PTHREAD_CANCELED的值是-1。可在標頭檔案pthread.h中找到它的定義:#define PTHREAD_CANCELED ((void *) -1)。因此當我們對一個已經被取消的執行緒使用pthread_join回收時,得到的返回值為-1。

【練習】:終止執行緒的三種方法。注意"取消點"的概念。                                    【pthrd_endof3.c】

終止執行緒方式

總結:終止某個執行緒而不終止整個程序,有三種方法:

  1. 從執行緒主函式return。這種方法對主控執行緒不適用,從main函式return相當於呼叫exit。
  2. 一個執行緒可以呼叫pthread_cancel終止同一程序中的另一個執行緒。
  3. 執行緒可以呼叫pthread_exit終止自己。

pthread_equal函式

比較兩個執行緒ID是否相等。

    int pthread_equal(pthread_t t1, pthread_t t2);

    有可能Linux在未來執行緒ID pthread_t 型別被修改為結構體實現。

控制原語對比

    程序            執行緒

    fork            pthread_create

    exit            pthread_exit

    wait            pthread_join

    kill            pthread_cancel

    getpid        pthread_self        名稱空間

接下來看程式碼:

#include<pthread.h>

#include<stdio.h>

#include<stdlib.h>

void *func1(void * f1)

{

    puts("我是第一個執行緒!我採用return的方式結束自己。");

    return (void*)770880;

}

void *func2(void * f2)

{

    puts("我是第二個執行緒!我採用pthread_exit的方式結束自己。");

    pthread_exit((void*)1314);

}

void *func3(void * f3)

{

    puts("我是第三個執行緒!我採用pthread_cancel的方式結束自己。");

    while (1)//可能會發生執行緒執行完但是主執行緒還沒有開始呼叫pthread_cancel函式。

        pthread_testcancel();//主動設定取消點

    return (void*)520;

}

int main(void)

{

    pthread_t pth[3];

    void *i;

    pthread_create((pth + 0), NULL, func1, NULL);

    pthread_join(pth[0], (void**)&i);

    printf("執行緒一的退出狀態:i = %d.\n", (int)i);

    pthread_create((pth + 1), NULL, func2, NULL);

    pthread_join(pth[1], (void**)&i);

    printf("執行緒二的退出狀態:i = %d.\n", (int)i);

    pthread_create((pth + 2), NULL, func3, NULL);

    pthread_cancel(pth[2]);//殺死

    pthread_join(pth[2], (void**)&i);

    printf("執行緒三的退出狀態:i = %d.\n", (int)i);

    return 0;

}

結果:

很簡單,就這樣吧。