回答這個(gè)問(wèn)題,首先得搞清楚線(xiàn)程關(guān)閉或者退出有哪些方式
線(xiàn)程的退出方式
如果進(jìn)程中的任何線(xiàn)程調(diào)用exit,_Exit或_exit,則整個(gè)進(jìn)程終止。類(lèi)似地,當(dāng)信號(hào)的默認(rèn)操作是終止進(jìn)程時(shí),發(fā)送到線(xiàn)程的信號(hào)將終止整個(gè)進(jìn)程。單個(gè)線(xiàn)程可以有三種方式退出其控制流程,而不會(huì)終止整個(gè)進(jìn)程。1線(xiàn)程可以簡(jiǎn)單地從線(xiàn)程處理程序中返回,返回值是線(xiàn)程的退出代碼。
2該線(xiàn)程可以被同一進(jìn)程中的另一個(gè)線(xiàn)程取消。
3該線(xiàn)程可以調(diào)用pthread_exi
線(xiàn)程退出的返回值
#include<pthread.h>voidpthread_exit(void*rval_ptr);#include<pthread.h>intpthread_join(pthread_tthread,void**rval_ptr);
pthread_join函數(shù)的rval_ptr參數(shù)是無(wú)類(lèi)型指針。進(jìn)程中的其他線(xiàn)程可通過(guò)調(diào)用pthread_join函數(shù)來(lái)使用rval_ptr指針,調(diào)用它線(xiàn)程將阻塞,直到指定的線(xiàn)程調(diào)用pthread_exit或從其線(xiàn)程處理程序中返回或被取消。如果只是從其線(xiàn)程處理程序返回,則rval_ptr將包含返回碼。如果線(xiàn)程被取消,則rval_ptr指定的內(nèi)存位置設(shè)置為PTHREAD_CANCELED。
通過(guò)調(diào)用pthread_join,自動(dòng)會(huì)將加入的線(xiàn)程放置在分離狀態(tài),如果線(xiàn)程已處于分離狀態(tài),則pthread_join可能會(huì)失敗,返回EINVAL。如果我們對(duì)線(xiàn)程的返回值不感興趣,我們可以將rval_ptr設(shè)置為NULL。在這種情況下,調(diào)用pthread_join允許我們等待指定的線(xiàn)程,但不去檢索線(xiàn)程的終止?fàn)顟B(tài)。
下圖顯示了如何從已終止的線(xiàn)程中獲取退出代碼
運(yùn)行結(jié)果:
lj@lj-PC:~$./ptest
thread1returning
thread2exiting
thread1exitcode1
thread2exitcode2
線(xiàn)程如何取消
一個(gè)線(xiàn)程可以通過(guò)調(diào)用pthread_cancel函數(shù)請(qǐng)求取消同一進(jìn)程中的另一個(gè)。
#include<pthread.h>intpthread_cancel(pthread_ttid);
在默認(rèn)情況下,pthread_cancel將使tid指定的線(xiàn)程的行為就像它使用PTHREAD_CANCELED參數(shù)調(diào)用pthread_exit一樣。但是,線(xiàn)程可以選擇忽略或以其他方式控制取消的方式。請(qǐng)注意,pthread_cancel不會(huì)等待線(xiàn)程終止。
線(xiàn)程可以安排函數(shù)在退出時(shí)被調(diào)用,這些函數(shù)稱(chēng)為線(xiàn)程清理處理程序。可以為一個(gè)線(xiàn)程建立多個(gè)清理處理程序。處理程序記錄在堆棧中,這意味著它們的執(zhí)行順序與它們注冊(cè)的順序相反。
#include<pthread.h>voidpthread_cleanup_push(void(*rtn)(void*),void*arg);voidpthread_cleanup_pop(intexecute);
當(dāng)線(xiàn)程執(zhí)行以下操作之一時(shí),pthread_cleanup_push函數(shù)會(huì)被調(diào)用
調(diào)用pthread_exit
回復(fù)取消請(qǐng)求
使用非零執(zhí)行參數(shù)調(diào)用pthread_cleanup_pop
如果execute參數(shù)設(shè)置為零,則不會(huì)調(diào)用cleanup函數(shù)。在任何一種情況下,pthread_cleanup_pop都會(huì)刪除最后一次調(diào)用pthread_cleanup_push所建立的清理處理程序。
下圖舉例如何使用線(xiàn)程清理處理程序。
運(yùn)行結(jié)果:
lj@lj-PC:~$./pclean
thread1start
thread1pushcomplete
thread2start
thread1exitcode1
thread2pushcomplete
cleanup:thread2secondhandler
cleanup:thread2firsthandler
thread2exitcode2
從輸出中,我們可以看到兩個(gè)線(xiàn)程都正常啟動(dòng)并退出,但只調(diào)用了第二個(gè)線(xiàn)程的清理處理程序。因此,如果線(xiàn)程是通過(guò)其處理函數(shù)直接返回而終止,則不會(huì)調(diào)用其清理處理程序,不過(guò)此行為在具體平臺(tái)實(shí)現(xiàn)之間會(huì)有所不同。另請(qǐng)注意,清理處理程序的調(diào)用順序與安裝它們的順序相反。
如果我們?cè)贔reeBSD或MacOSX上運(yùn)行相同的程序,我們會(huì)發(fā)現(xiàn)該程序會(huì)導(dǎo)致段錯(cuò)誤。發(fā)生這種情況是因?yàn)樵谶@些系統(tǒng)上,pthread_cleanup_push實(shí)現(xiàn)為在堆棧上存儲(chǔ)某些上下文的宏。當(dāng)線(xiàn)程1在對(duì)pthread_cleanup_push的調(diào)用和對(duì)pthread_cleanup_pop的調(diào)用之間返回時(shí),堆棧被覆蓋,并且這些平臺(tái)在調(diào)用清理處理程序時(shí)嘗試使用此(已損壞的)上下文。在SingleUNIXSpecification中,在對(duì)pthread_cleanup_push和pthread_cleanup_pop的一對(duì)匹配調(diào)用之間返回會(huì)導(dǎo)致未定義的行為。在這兩個(gè)函數(shù)之間返回的唯一可移植方法是調(diào)用pthread_exit。
線(xiàn)程和進(jìn)程的類(lèi)似操作
從上文我們可以看到線(xiàn)程和進(jìn)程的相似之處,見(jiàn)如下表格:
講了這么多,還有好多細(xì)節(jié)沒(méi)有講到,只要詳細(xì)的了解了這些細(xì)節(jié),我相信關(guān)于你的這個(gè)問(wèn)題“l(fā)inux下C中怎么讓才能安全關(guān)閉線(xiàn)程”自然就有了答案。