執行緒的終止

2021-08-17 22:06:18 字數 4192 閱讀 1486

1.程序中的任意執行緒呼叫了exit、_exit 或者 _exit,那麼整個程序就會終止。

2.如果預設的動作是終止程序,那麼傳送到執行緒的訊號也會終止整個程序。

在不終止程序的情況下停止單個執行緒:

1.執行緒可以從啟動例程中返回(return),返回值是執行緒的退出碼。

2.執行緒可以被同一程序中的其他執行緒取消。

3.執行緒呼叫pthread_exit。

#include < pthread. h>

void pthread_exit( void *rval_ptr);

//結束執行緒

rval_ptr 引數是乙個無型別指標,儲存執行緒的退出碼。

#include < pthread. h>

int pthread_join( pthread_t thread, void **rval_ptr);

//返回值:若成功,返回0;否則,返回錯誤編碼。

呼叫該函式的執行緒將一直阻塞,等待直到指定的執行緒終止。

如果執行緒簡單地從它的啟動例程返回,rval_ptr就包含返回碼。如果執行緒被取消,由rval_ptr指定的記憶體單元就被設定為pthread_canceled,如果不需要知道執行緒的返回值,則可以設定為null。

#include 

#include

#include

#include

void *thr_fn1(void *arg)

void *thr_fn2(void *arg)

int main(int argc, const

char * argv)

err = pthread_create(&tid2, null, thr_fn2, null);//建立子執行緒1

if (err != 0)

err = pthread_join(tid1, &tret); //阻塞等待執行緒1結束

if (err != 0)

printf("thread 1 exit code %ld\n",(long)tret);

err = pthread_join(tid2, &tret);//阻塞等待執行緒2結束

if (err != 0)

printf("thread 2 exit code %ld\n",(long)tret);

exit(0);

}

執行結果:

thread 1 returning

thread 2 exiting

thread 1

exit code 1

thread 2

exit code 2

program ended with

exit code: 0

#include < pthread. h>

int pthread_cancel( pthread_t tid);

//返回值:若成功,返回0;否則,返回錯誤碼。

執行緒可以通過呼叫pthread_cancel來取消同一程序中的其他執行緒。

pthread_cancel函式會使得由tid標識的執行緒的行為表現為如同呼叫引數pthread_canceled的pthread_exit函式,但是,執行緒可以選擇忽略取消或者控制如何被取消。

注意:pthread_cancel不等待執行緒終止,它僅僅提出要求。

執行緒可以安排它退出時需要呼叫的函式,這樣的函式稱為執行緒清理處理程式。

乙個執行緒可以安排多個執行緒清理處理程式,這些處理程式記錄在棧中,也就是說,它們的執行順序與它們註冊時相反。

#include < pthread. h>

void pthread_cleanup_push( void (*rtn)( void *), void *arg);

void pthread_cleanup_pop( int execute);

當執行緒執行以下動作時,清理函式rtn是由pthread_ cleanup_ push函式排程的,呼叫時,只有乙個引數arg:

1.呼叫pthread_exit時;

2.響應取消請求時;

3.用非零execute引數呼叫pthread_ cleanup_ pop函式時;

如果execute引數為0,清理函式將不被呼叫。

注意:不管發生上述哪種情況,pthread_cleanup_pop都將刪除上一次pthread_cleanup_push呼叫建立的清理函式,pthread_cleanup_pop一次只清理乙個,所以一般在使用時要pthread_cleanup_push和pthread_cleanup_pop成對出現,否則有可能編譯不通過。

例項

#include 

#include

#include

#include

void cleanup(void *arg)

void *thr_fn1(void *arg)

//一般pop和push是成對出現的,因為有些平台是用巨集定義的函式,可能定義時push後面多帶了個『』,所以用0作為引數的pop和push進行配對

pthread_cleanup_pop(0);

pthread_cleanup_pop(0);

return ((void *)1);

}void *thr_fn2(void *arg)

//一般pop和push是成對出現的,因為有些平台是用巨集定義的函式,可能定義時push後面多帶了個『』,所以用0作為引數的pop和push進行配對

pthread_cleanup_pop(0);

pthread_cleanup_pop(0);

return ((void *)2);

}int main(void)

err = pthread_create(&tid2, null, thr_fn2, (void *)1);

if (err != 0)

err = pthread_join(tid1, &tret);

if (err != 0)

printf("thread 1 exit code %ld\n",(long)tret);

err = pthread_join(tid2, &tret);

if (err != 0)

printf("thread 2 exit code %ld\n",(long)tret);

exit(0);

}

執行結果:

thread 1 start

thread 1 push complete

cleanup: thread 1

second

handler

cleanup: thread 1

first

handler

thread 1 exit code 1

thread 2

start

thread 2 push complete

cleanup: thread 2

second

handler

cleanup: thread 2

first

handler

thread 2 exit code 2

program ended with exit code: 0

注意:

後push的清理函式先執行,棧式記錄。

pthread_cleanup_push和pthread_cleanup_pop之間不能呼叫retrn,否則有可能出現段錯誤而使程式崩潰。

因為某些平台下這兩個函式是用巨集定義實現的,巨集把某些上下文存放到棧上,而清理函式也是被放到棧上。當執行緒1在呼叫pthread_cleanup_push和呼叫pthread_cleanup_pop之間返回時,棧已被改寫(return後相應的函式就得出棧,棧被改變),而再次呼叫清理函式時就使用了這個被改變的棧,上下文內容被破壞,就出現段錯誤崩潰,所以使用清理函式的執行緒結束時應該呼叫pthread_exit而不應該使用return。

可以呼叫pthread_ detach分離執行緒。

#include < pthread. h>

int pthread_ detach( pthread_ t tid);

//返回值:若成功,返回0;否則返回失敗編碼。

執行緒 終止執行緒執行

stop 方法 缺點 強制終止會丟資料 不建議使用 public class myfile catch interruptedexception e 5秒後終止執行緒 t.stop 已過時,強制終止會丟資料 class myrunnable implements runnable catch int...

多執行緒 執行緒終止

stop 中止執行緒,並且清除監視器鎖的資訊,可能導致執行緒安全問題。destroy 從未實現過這個方法 public class demo thread.print public class stopthread extends thread catch interruptedexception ...

執行緒終止的問題

有兩種情況可以使執行緒結束 控制函式結束或者根本就不允許執行緒完成,而提前終止它。我們可以想象在 word中進行後台列印,如果列印結束了,那執行緒就可以結束了。如果使用者中止了列印,那後台列印執行緒也要終止了。本文將主要介紹對這兩種情況的實現,並且介紹如何獲得執行緒的結束 對於工作執行緒,結束它是比...