關鍵:
pthread_cancel函式傳送
終止訊號
pthread_setcancelstate函式
設定終止方式
pthread_testcancel函式取消執行緒
(另一功能是:設定取消點)
1 執行緒取消的定義
一般情況下,執行緒在其主體函式退出的時候會自動終止,但同時也可以因為接收到另乙個執行緒發來的終止(取消)請求而強制終止。
2 執行緒取消的語義
執行緒取消的方法是向目標執行緒發cancel訊號(pthread_cancel函式傳送
cancel訊號),但如何處理cancel訊號則由目標執行緒自己決定,或者忽略、或者立即終止、或者繼續執行至cancelation-point(取消點)
,由不同的cancelation狀態(pthread_setcancelstate函式設定狀態
)決定。
執行緒接收到cancel訊號的預設處理(即pthread_create()建立執行緒的預設狀態)是繼續執行至取消點,也就是說設定乙個canceled狀態,執行緒繼續執行,只有執行至cancelation-point的時候才會退出。
3 取消點
根據posix標準,pthread_join()、pthread_testcancel()、pthread_cond_wait()、 pthread_cond_timedwait()、sem_wait()、sigwait()等函式以及read()、write()等會引起阻塞的系統呼叫都是cancelation-point,而其他pthread函式都不會引起cancelation動作。但是pthread_cancel的手冊頁聲稱,由於linuxthread庫與c庫結合得不好,因而目前c庫函式都不是cancelation-point;但cancel訊號會使執行緒從阻塞的系統呼叫中退出,並置eintr錯誤碼,因此可以在需要作為cancelation-point的系統呼叫前後呼叫 pthread_testcancel(),從而達到posix標準所要求的目標,即如下**段:
pthread_testcancel();
retcode = read(fd, buffer, length);
pthread_testcancel();
4 程式設計方面的考慮
如果執行緒處於無限迴圈中,且迴圈體內沒有執行至取消點的必然路徑,則執行緒無法由外部其他執行緒的取消請求而終止。因此在這樣的迴圈體的必經路徑上應該加入pthread_testcancel()呼叫。
5 與執行緒取消相關的pthread函式
int pthread_cancel(pthread_t thread)
傳送終止訊號給thread執行緒,如果成功則返回0,否則為非0值。傳送成功並不意味著thread會終止。
int pthread_setcancelstate(int state, int *oldstate)
設定本執行緒對cancel訊號的反應,state有兩種值:pthread_cancel_enable(預設)和 pthread_cancel_disable,分別表示收到訊號後設為cancled狀態和忽略cancel訊號繼續執行;old_state如果不為 null則存入原來的cancel狀態以便恢復。
int pthread_setcanceltype(int type, int *oldtype)
設定本執行緒取消動作的執行時機,type由兩種取值:pthread_cancel_deffered和 pthread_cancel_asychronous,僅當cancel狀態為enable時有效,分別表示收到訊號後繼續執行至下乙個取消點再退出和立即執行取消動作(退出);oldtype如果不為null則存入運來的取消動作型別值。
void pthread_testcancel(void)
功能一:設定取消點;
功能二:檢查本執行緒是否處於canceld狀態,如果是,則進行取消動作,否則直接返回。
**:
#include
#include
#include
#include
#include
#define thread_max 4
pthread_mutex_t mutex;
pthread_t thread[thread_max];
static int tries;
static int started;
void print_it(int *arg)
void *search_num(int arg)
*/srand(arg);
num = rand()&0xffffff;
//pthread_mutex_unlock(&mutex);
printf("thread num %lx\n",tid);
ntries = 0;
pthread_setcancelstate(pthread_cancel_enable,null);
pthread_setcanceltype(pthread_cancel_deferred,null);
pthread_cleanup_push((void *)print_it,(void *)&ntries);
while(1)
pthread_testcancel();
}tries = ntries;
//pthread_mutex_unlock(&mutex); //如果加上這句話,將會有好幾個執行緒找到主函式中設定的值pid
printf("thread %lx found the number!\n",tid);
for(j = 0;j
}break;
}if(ntries%100 == 0)}}
pthread_cleanup_pop(0);
return (void *)0;
}int main()
for(i = 0; i < thread_max; i++)
printf("it took %d tries ot find the number!\n",tries);
return 0;}
執行結果:
search the num of 6531
-----------i = 0--------------
thread num b6fbcb70
thread num b67bbb70
thread num b5fbab70
thread num b77bdb70
----------thread num b67bbb70-------------
thread b67bbb70 found the number!
----------thread num b6fbcb70-------------
----------thread num b77bdb70-------------
----------2busy2-----------
----------thread num b5fbab70-------------
----------2busy2-----------
thread b5fbab70 was canceled on its 1174527 try.
thread b77bdb70 was canceled on its 1023100 try.
-----------i = 1--------------
thread b6fbcb70 was canceled on its 1174527 try.
-----------i = 2--------------
-----------i = 3--------------
it took 1174527 tries ot find the number!
從這結果裡你有沒有看出什麼呢?呵呵~.~
LINUX多執行緒程式設計之建立,等待,取消執行緒
h7n9禽流感來啦,多人死亡,又感覺到了03年我在北京時的非典氣氛。家裡菜桌上肉明顯沒了。睡一覺起來,肚子裡再沒有肉貨,清明節學習的計畫不能停止!現在進入多執行緒學習啦。由於linux程序間的通訊占用資源蠻大的,所以設定了執行緒函式,只複製棧,其它同享。當然,執行緒之間,也存在著同步機制啦 互斥鎖,...
多執行緒程式設計之執行緒的封裝
前人總結出,乙個執行緒安全的class應當滿足的條件 1.從多個執行緒訪問時,其表現出正確的行為,無論作業系統如何排程這些執行緒,無論這些執行緒的執行順序如何交織。2.呼叫端 無需額外的同步或其他協調動作 在寫多執行緒程式時腦子裡要有這樣的意識,下面我總結了幾條比較具體的注意事項。使用多執行緒要考慮...
多執行緒程式設計之執行緒的封裝
前人總結出,乙個執行緒安全的class應當滿足的條件 1.從多個執行緒訪問時,其表現出正確的行為,無論作業系統如何排程這些執行緒,無論這些執行緒的執行順序如何交織。2.呼叫端 無需額外的同步或其他協調動作 在寫多執行緒程式時腦子裡要有這樣的意識,下面我總結了幾條比較具體的注意事項。使用多執行緒要考慮...