pthread_kill和pthread_cancel

pthread_kill和pthread_cancel
爲了講述標題兩個函數,必須先介紹一下pthread線程庫。
pthread線程庫是遵循POSIX標準開發的,工作非常穩定,性能也不差,
所以在Linux下是最常用的線程庫。但從調用上看,pthread線程應該仍然屬於用戶級的線程庫,
其實用戶級還是內核級的關鍵區別只在於線程的調度是由內核還是用戶庫來完成,用戶級對於
一般的服務器工作而言是沒用問題的。
pthread_kill函數的功能是向指定線程發送信號,信號爲0時用於檢查此線程ID的線程是否存活。
pthread_cancel函數的功能是給線程發送取消信號,使線程從取消點退出。
從函數功能上理解沒用任何問題,但實際應用中發現創建線程超過3個,且一起退出時會發生異
常操作;分別對應兩個函數進行測試,發現每個函數執行時如果線程已經退出,都會出現異常
情況。比較奇怪的是跟創建的線程數量有關,超過3個才發生;小於3個不發生,具體的原因不清楚。
另外測試給這兩個函數錯誤的線程ID,也會造成異常的情況;線程ID正確,且沒用退出則沒用問題。
沒用辦法,只好修改了自己的實現函數,在每個線程退出後不再調用標題函數。對於線程保存的數據
結構,每個線程僅休眠500ms,就刪除對應的數據,測試沒用發現問題。500ms是多次測試的經驗值,
一般線程都可以正常退出了。






pthread_kill:


別被名字嚇到,pthread_kill可不是kill,而是向線程發送signal。還記得signal嗎,
大部分signal的默認動作是終止進程的運行,所以,我們纔要用signal()去抓信號並加上處理函數。


int pthread_kill(pthread_t thread, int sig);


向指定ID的線程發送sig信號,如果線程代碼內不做處理,則按照信號默認的行爲影響整個進程,
也就是說,如果你給一個線程發送了SIGQUIT,但線程卻沒有實現signal處理函數,則整個進程退出。


pthread_kill(threadid, SIGKILL)也一樣,殺死整個進程。
如果要獲得正確的行爲,就需要在線程內實現signal(SIGKILL,sig_handler)了。


所以,如果int sig的參數不是0,那一定要清楚到底要幹什麼,而且一定要實現線程的信號處理函數,
否則,就會影響整個進程。




OK,如果int sig是0呢,這是一個保留信號,一個作用是用來判斷線程是不是還活着。


我們來看一下pthread_kill的返回值:
成功:0
線程不存在:ESRCH
信號不合法:EINVAL


所以,pthread_kill(threadid,0)就很有用啦。


int kill_rc = pthread_kill(thread_id,0);


if(kill_rc == ESRCH)
printf("the specified thread did not exists or already quit\n");
else if(kill_rc == EINVAL)
printf("signal is invalid\n");
else
printf("the specified thread is alive\n");


上述的代碼就可以判斷線程是不是還活着了。pthread_kill和pthread_cancel
爲了講述標題兩個函數,必須先介紹一下pthread線程庫。
pthread線程庫是遵循POSIX標準開發的,工作非常穩定,性能也不差,
所以在Linux下是最常用的線程庫。但從調用上看,pthread線程應該仍然屬於用戶級的線程庫,
其實用戶級還是內核級的關鍵區別只在於線程的調度是由內核還是用戶庫來完成,用戶級對於
一般的服務器工作而言是沒用問題的。
pthread_kill函數的功能是向指定線程發送信號,信號爲0時用於檢查此線程ID的線程是否存活。
pthread_cancel函數的功能是給線程發送取消信號,使線程從取消點退出。
從函數功能上理解沒用任何問題,但實際應用中發現創建線程超過3個,且一起退出時會發生異
常操作;分別對應兩個函數進行測試,發現每個函數執行時如果線程已經退出,都會出現異常
情況。比較奇怪的是跟創建的線程數量有關,超過3個才發生;小於3個不發生,具體的原因不清楚。
另外測試給這兩個函數錯誤的線程ID,也會造成異常的情況;線程ID正確,且沒用退出則沒用問題。
沒用辦法,只好修改了自己的實現函數,在每個線程退出後不再調用標題函數。對於線程保存的數據
結構,每個線程僅休眠500ms,就刪除對應的數據,測試沒用發現問題。500ms是多次測試的經驗值,
一般線程都可以正常退出了。






pthread_kill:


別被名字嚇到,pthread_kill可不是kill,而是向線程發送signal。還記得signal嗎,
大部分signal的默認動作是終止進程的運行,所以,我們纔要用signal()去抓信號並加上處理函數。


int pthread_kill(pthread_t thread, int sig);


向指定ID的線程發送sig信號,如果線程代碼內不做處理,則按照信號默認的行爲影響整個進程,
也就是說,如果你給一個線程發送了SIGQUIT,但線程卻沒有實現signal處理函數,則整個進程退出。


pthread_kill(threadid, SIGKILL)也一樣,殺死整個進程。
如果要獲得正確的行爲,就需要在線程內實現signal(SIGKILL,sig_handler)了。


所以,如果int sig的參數不是0,那一定要清楚到底要幹什麼,而且一定要實現線程的信號處理函數,
否則,就會影響整個進程。




OK,如果int sig是0呢,這是一個保留信號,一個作用是用來判斷線程是不是還活着。


我們來看一下pthread_kill的返回值:
成功:0
線程不存在:ESRCH
信號不合法:EINVAL


所以,pthread_kill(threadid,0)就很有用啦。


int kill_rc = pthread_kill(thread_id,0);


if(kill_rc == ESRCH)
printf("the specified thread did not exists or already quit\n");
else if(kill_rc == EINVAL)
printf("signal is invalid\n");
else
printf("the specified thread is alive\n");


上述的代碼就可以判斷線程是不是還活着了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章