首頁>Club>
14
回覆列表
  • 1 # 拉那烈

    回答這個問題,首先得搞清楚執行緒關閉或者退出有哪些方式

    執行緒的退出方式如果程序中的任何執行緒呼叫exit,_Exit或_exit,則整個程序終止。 類似地,當訊號的預設操作是終止程序時,傳送到執行緒的訊號將終止整個程序。單個執行緒可以有三種方式退出其控制流程,而不會終止整個程序。1執行緒可以簡單地從執行緒處理程式中返回,返回值是執行緒的退出程式碼。2該執行緒可以被同一程序中的另一個執行緒取消。3該執行緒可以呼叫pthread_exi執行緒退出的返回值#include <pthread.h> void pthread_exit(void *rval_ptr);#include <pthread.h> int pthread_join(pthread_t thread, void **rval_ptr);

    pthread_join函式的rval_ptr引數是無型別指標。程序中的其他執行緒可透過呼叫pthread_join函式來使用rval_ptr指標,呼叫它執行緒將阻塞,直到指定的執行緒呼叫pthread_exit或從其執行緒處理程式中返回或被取消。如果只是從其執行緒處理程式返回,則rval_ptr將包含返回碼。如果執行緒被取消,則rval_ptr指定的記憶體位置設定為PTHREAD_CANCELED。

    透過呼叫pthread_join,自動會將加入的執行緒放置在分離狀態,如果執行緒已處於分離狀態,則pthread_join可能會失敗,返回EINVAL。如果我們對執行緒的返回值不感興趣,我們可以將rval_ptr設定為NULL。在這種情況下,呼叫pthread_join允許我們等待指定的執行緒,但不去檢索執行緒的終止狀態。

    下圖顯示瞭如何從已終止的執行緒中獲取退出程式碼

    執行結果:

    lj@lj-PC:~$ ./ptest

    thread 1 returning

    thread 2 exiting

    thread 1 exit code 1

    thread 2 exit code 2

    執行緒如何取消

    一個執行緒可以透過呼叫pthread_cancel函式請求取消同一程序中的另一個。

    #include <pthread.h> int pthread_cancel(pthread_t tid);

    在預設情況下,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);

    當執行緒執行以下操作之一時,pthread_cleanup_push函式會被呼叫

    呼叫pthread_exit

    回覆取消請求

    使用非零執行引數呼叫pthread_cleanup_pop

    下圖舉例如何使用執行緒清理處理程式。

    執行結果:

    lj@lj-PC:~$ ./pclean

    thread 1 start

    thread 1 push complete

    thread 2 start

    thread 1 exit code 1

    thread 2 push complete

    cleanup: thread 2 second handler

    cleanup: thread 2 first handler

    thread 2 exit code 2

    從輸出中,我們可以看到兩個執行緒都正常啟動並退出,但只調用了第二個執行緒的清理處理程式。因此,如果執行緒是透過其處理函式直接返回而終止,則不會呼叫其清理處理程式,不過此行為在具體平臺實現之間會有所不同。另請注意,清理處理程式的呼叫順序與安裝它們的順序相反。

    如果我們在FreeBSD或Mac OS X上執行相同的程式,我們會發現該程式會導致段錯誤。發生這種情況是因為在這些系統上,pthread_cleanup_push實現為在堆疊上儲存某些上下文的宏。當執行緒1在對pthread_cleanup_push的呼叫和對pthread_cleanup_pop的呼叫之間返回時,堆疊被覆蓋,並且這些平臺在呼叫清理處理程式時嘗試使用此(已損壞的)上下文。在Single UNIX Specification中,在對pthread_cleanup_push和pthread_cleanup_pop的一對匹配呼叫之間返回會導致未定義的行為。在這兩個函式之間返回的唯一可移植方法是呼叫pthread_exit。

    執行緒和程序的類似操作

    從上文我們可以看到執行緒和程序的相似之處,見如下表格:

    講了這麼多,還有好多細節沒有講到,只要詳細的瞭解了這些細節,我相信關於你的這個問題“linux下C中怎麼讓才能安全關閉執行緒”自然就有了答案。

  • 中秋節和大豐收的關聯?
  • DNF11週年獎勵出爐了,都有哪些獎勵最值得關注?對賬號角色提升有多大?