国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

線程資源釋放 問題解決

2019-11-08 02:20:22
字體:
供稿:網(wǎng)友

一般來說,Posix的線程終止有兩種情況:正常終止和非正常終止。線程主動調(diào)用pthread_exit()或者從線程函數(shù)中return都將使線程正常退出,這是可預(yù)見的退出方式;非正常終止是線程在其他線程的干預(yù)下,或者由于自身運(yùn)行出錯(比如訪問非法地址)而退出,這種退出方式是不可預(yù)見的。

不論是可預(yù)見的線程終止還是異常終止,都會存在資源釋放的問題,在不考慮因運(yùn)行出錯而退出的前提下,如何保證線程終止時能順利的釋放掉自己所占用的資源,特別是鎖資源,就是一個必須考慮解決的問題。

最經(jīng)常出現(xiàn)的情形是資源獨(dú)占鎖的使用:線程為了訪問臨界資源而為其加上鎖,但在訪問過程中被外界取消,如果線程處于響應(yīng)取消狀態(tài),且采用異步方式響應(yīng),或者在打開獨(dú)占鎖以前的運(yùn)行路徑上存在取消點(diǎn),則該臨界資源將永遠(yuǎn)處于鎖定狀態(tài)得不到釋放。外界取消操作是不可預(yù)見的,因此的確需要一個機(jī)制來簡化用于資源釋放的編程。

在POSIX線程API中提供了一個pthread_cleanup_push()/pthread_cleanup_pop()函數(shù)對用于自動釋放資源。 –從pthread_cleanup_push()的調(diào)用點(diǎn)到pthread_cleanup_pop()之間的程序段中的終止動作(包括調(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ù)棧,多次對pthread_cleanup_push()的調(diào)用將在清理函數(shù)棧中形成一個函數(shù)鏈,在執(zhí)行該函數(shù)鏈時按照壓棧的相反順序彈出。execute參數(shù)表示執(zhí)行到pthread_cleanup_pop()時是否在彈出清理函數(shù)的同時執(zhí)行該函數(shù),為0表示不執(zhí)行,非0為執(zhí)行;這個參數(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()帶有一個”{“,而pthread_cleanup_pop()帶有一個”}”,因此這兩個函數(shù)必須成對出現(xiàn),且必須位于程序的同一級別的代碼段中才能通過編譯。在下面的例子里,當(dāng)線程在”do some work”中終止時,將主動調(diào)用pthread_mutex_unlock(mut),以完成解鎖動作。

pthread_cleanup_push(pthread_mutex_unlock, (void *) &mut);pthread_mutex_lock(&mut);/* do some work */pthread_mutex_unlock(&mut);pthread_cleanup_pop(0);

必須要注意的是,如果線程處于PTHREAD_CANCEL_ASYNCHRONOUS狀態(tài),上述代碼段就有可能出錯,因?yàn)镃ANCEL事件有可能在pthread_cleanup_push()和pthread_mutex_lock()之間發(fā)生,或者在pthread_mutex_unlock()和pthread_cleanup_pop()之間發(fā)生,從而導(dǎo)致清理函數(shù)unlock一個并沒有加鎖的mutex變量,造成錯誤。因此,在使用清理函數(shù)的時候,都應(yīng)該暫時設(shè)置成PTHREAD_CANCEL_DEFERRED模式。為此,POSIX的linux實(shí)現(xiàn)中還提供了一對不保證可移植的pthread_cleanup_push_defer_np()/pthread_cleanup_pop_defer_np()擴(kuò)展函數(shù),功能與以下 代碼段相當(dāng):

{ int oldtype; pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype); pthread_cleanup_push(routine, arg); ... pthread_cleanup_pop(execute); pthread_setcanceltype(oldtype, NULL); }
發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 祥云县| 五家渠市| 方正县| 郁南县| 正阳县| 巴林右旗| 盘山县| 左权县| 门头沟区| 奉节县| 宿迁市| 会理县| 姜堰市| 大足县| 茶陵县| 东方市| 高密市| 巨野县| 延津县| 梅州市| 古田县| 桐乡市| 娄烦县| 萨嘎县| 苏尼特右旗| 濉溪县| 仪陇县| 辛集市| 额敏县| 宁城县| 潜江市| 青岛市| 土默特左旗| 若尔盖县| 达州市| 祁阳县| 健康| 霞浦县| 平阴县| 溆浦县| 泰宁县|