5、线程终止方式:pthread_cleanup_push/pthread_cleanup_pop()
??? 以下內(nèi)容根據(jù)【1】進(jìn)行整理。關(guān)于取消點(diǎn),將在后面進(jìn)一步討論。
1、一般來說,Posix的線程終止有兩種情況:正常終止和非正常終止。線程主動(dòng)調(diào)用pthread_exit()或者從線程函數(shù)中return都將使線程正常退出,這是可預(yù)見的退出方式;非正常終止是線程在其他線程的干預(yù)下,或者由于自身運(yùn)行出錯(cuò)(比如訪問非法地址)而退出,這種退出方式是不可預(yù)見的。
2、線程終止時(shí)的清理
??? 不論是可預(yù)見的線程終止還是異常終止,都會(huì)存在資源釋放的問題,在不考慮因運(yùn)行出錯(cuò)而退出的前提下,如何保證線程終止時(shí)能順利的釋放掉自己所占用的資源,特別是鎖資源,就是一個(gè)必須考慮解決的問題。
??? 最經(jīng)常出現(xiàn)的情形是資源獨(dú)占鎖的使用:線程為了訪問臨界資源而為其加上鎖,但在訪問過程中被外界取消,如果線程處于響應(yīng)取消狀態(tài),且采用異步方式響應(yīng),或者在打開獨(dú)占鎖以前的運(yùn)行路徑上存在取消點(diǎn),則該臨界資源將永遠(yuǎn)處于鎖定狀態(tài)得不到釋放。外界取消操作是不可預(yù)見的,因此的確需要一個(gè)機(jī)制來簡(jiǎn)化用于資源釋放的編程。
??? 在POSIX線程API中提供了一個(gè)pthread_cleanup_push()/?pthread_cleanup_pop()函數(shù)對(duì)用于自動(dòng)釋放資源—從pthread_cleanup_push()的調(diào)用點(diǎn)到pthread_cleanup_pop()之間的程序段中的終止動(dòng)作(包括調(diào)用pthread_exit()和取消點(diǎn)終止)都將執(zhí)行pthread_cleanup_push()所指定的清理函數(shù)。
API定義如下:
void pthread_cleanup_push(void (*routine) (void *), void *arg)
void pthread_cleanup_pop(int execute)
??? pthread_cleanup_push()/pthread_cleanup_pop()采用先入后出的棧結(jié)構(gòu)管理,void routine(void *arg)函數(shù)在調(diào)用pthread_cleanup_push()時(shí)壓入清理函數(shù)棧,多次對(duì)pthread_cleanup_push() 的調(diào)用將在清理函數(shù)棧中形成一個(gè)函數(shù)鏈;從pthread_cleanup_push的調(diào)用點(diǎn)到pthread_cleanup_pop之間的程序段中的終止動(dòng)作(包括調(diào)用pthread_exit()和異常終止,不包括return)都將執(zhí)行pthread_cleanup_push()所指定的清理函數(shù)。
??????? 在執(zhí)行該函數(shù)鏈時(shí)按照壓棧的相反順序彈出。execute參數(shù)表示執(zhí)行到 pthread_cleanup_pop()時(shí)是否在彈出清理函數(shù)的同時(shí)執(zhí)行該函數(shù),為0表示不執(zhí)行,非0為執(zhí)行;這個(gè)參數(shù)并不影響異常終止時(shí)清理函數(shù)的執(zhí)行。
??? pthread_cleanup_push()/pthread_cleanup_pop()是以宏方式實(shí)現(xiàn)的,這是pthread.h中的宏定義:
#define pthread_cleanup_push(routine,arg) \
{
struct _pthread_cleanup_buffer _buffer; \
_pthread_cleanup_push (&_buffer, (routine), (arg));
#define pthread_cleanup_pop(execute) \
_pthread_cleanup_pop (&_buffer, (execute)); \
??? }
??? 可見,pthread_cleanup_push()帶有一個(gè)"{",而pthread_cleanup_pop()帶有一個(gè)"}",因此這兩個(gè)函數(shù)必須成對(duì)出現(xiàn),且必須位于程序的同一級(jí)別的代碼段中才能通過編譯。
??? 在下面的例子里,當(dāng)線程在"do some work"中終止時(shí),將主動(dòng)調(diào)用pthread_mutex_unlock(mut),以完成解鎖動(dòng)作。
pthread_cleanup_push(pthread_mutex_unlock, (void*) &mut);
pthread_mutex_lock(&mut);
/* do some work */
pthread_mutex_unlock(&mut);
pthread_cleanup_pop(0);
【1】 http://wenku.baidu.com/view/fd4a162e0066f5335a812191.html
總結(jié)
以上是生活随笔為你收集整理的5、线程终止方式:pthread_cleanup_push/pthread_cleanup_pop()的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 制作Ubuntu16.04系统盘
- 下一篇: 做人与做事的心态