Linux:結束線程的三種方式


一般情況下,線程終止后,其終止狀態一直保留到其它線程調用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;

}

結果:

很簡單,就這樣吧。


免責聲明!

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



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