上次說了如何去建立一個線程及如何向線程中傳遞一個參數那麼這次我們說一下如何終止一個線程。
如進程中調用exit,_exit使進程結束一樣,線程也可以通過類似的方法結束。
一、線程的執行體結束線程自然結束。
二、可以通過調用pthread_exit使程式結束。
pthread_exit 的原型為:
void pthread_exit(void *value_ptr);
value_ptr是一個無類型傳回值,其他線程可以通過調用phread_join來獲得這個值。
phread_join 的原型為:
int pthread_join(pthread_t thread, void **value_ptr);
調用pthread_join可以等待線程thread的退出並獲得退出時的狀態,如果不關心線程傳回值的話,value_ptr可以置為NULL,下面我們用一個常式說明這兩個函數的使用方法。
#include <stdio.h></p><p>#include <pthread.h></p><p>void *thread_a(void *arg)</p><p>{</p><p> printf("thread 1 enter/n");</p><p> pthread_exit((void *)1);</p><p>}</p><p>void *thread_b(void *arg)</p><p>{</p><p> printf("thread 2 enter/n");</p><p> pthread_exit((void *)2);</p><p>}</p><p>int main(int argc, char **argv)</p><p>{</p><p> pthread_t tid_a,tid_b;</p><p> int err;</p><p> void *value_ptr;</p><p> err = pthread_create(&tid_a,NULL,thread_a,NULL);</p><p> if(err < 0)</p><p> {</p><p> perror("pthread_create thread_a");</p><p> }</p><p> err = pthread_create(&tid_b,NULL,thread_b,NULL);</p><p> if(err < 0)</p><p> {</p><p> perror("pthread_create thread_a");</p><p> }</p><p> pthread_join(tid_b,&value_ptr);</p><p> printf("phtread %d exit!/n",(int)value_ptr);</p><p> pthread_join(tid_a,&value_ptr);</p><p> printf("phtread %d exit!/n",(int)value_ptr);</p><p> sleep(5);</p><p> printf("the main close/n");</p><p> return 0;</p><p>}<br />
三、被統一線程中的其他線程取消而結束。
線程可以通過調用pthread_cancel函數向同一進程中的其他線程發送取消的訊號,但是這個先好的響應可以設定,可以設定為立即終止或忽略。所以發送取消訊號並不意味著線程就會終止。
與線程取消相關的函數有:
phtread_cancel原型為:
int pthread_cancel(pthread_t thread);
這個函數向線程thread發送終止訊號。
pthread_setcancelstate原型為:
int pthread_setcancelstate(int state, int *oldstate);
這個函數設定線程接收到終止訊號的反應,state有兩種值:PHTREAD_CANCEL_ENABLE(預設為這個狀態)和PHREAD_CANCEL_DISABLE,這兩個值分別代表接受掉終止訊號終止線程和或略這個訊號。oldstate用來存放線程原來的狀態用來以後恢複只用,如不用回複可以設定為NULL。
pthread_setcanceltype原型為:
int pthread_setcanceltype(int type, int *oldtype);
這個函數用來設定線程接收到終止訊號的執行時間,type也是有兩個值:PTHREAD_CANCEL_DEFFERED和PTHREAD_CANCEL_ASYCHRONOUS,這兩個值分別表示線程接收到終止訊號是運行到下一個取消點退出還是立即退出。同樣oldtype也是用來存放線程原來的狀態。
pthread_testcancel原型為:
void pthread_testcancel(void);
檢查線程是否處於canceld狀態如果是則執行取消動作否則立即返回。
下面用一個常式說明這幾個函數的使用。
#include <stdio.h></p><p>#include <pthread.h></p><p>void *thread_a(void *arg)</p><p>{</p><p> if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL) != 0)</p><p> {</p><p> perror("setcancelstate");</p><p> }</p><p> if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL) != 0)</p><p> {</p><p> perror("setcancelsype");</p><p> }</p><p> while(1)</p><p> {</p><p> sleep(1);</p><p> printf("thread_a/n");</p><p> pthread_testcancel();</p><p> }</p><p>}</p><p>void *thread_b(void *arg)</p><p>{</p><p> if(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL) != 0)</p><p> {</p><p> perror("setcancelstate");</p><p> }</p><p> while(1)</p><p> {</p><p> sleep(1);</p><p> printf("thread_b/n");</p><p> pthread_testcancel();</p><p> }</p><p>}</p><p>void *thread_c(void *arg)</p><p>{</p><p> if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL) != 0)</p><p> {</p><p> perror("setcancelstate");</p><p> }</p><p> if(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL) != 0)</p><p> {</p><p> perror("setcancelsype");</p><p> }</p><p> while(1)</p><p> {</p><p> sleep(1);</p><p> printf("thread_c/n");</p><p> pthread_testcancel();</p><p> }</p><p>}</p><p>int main(int argc, char **argv)</p><p>{</p><p> pthread_t tid_a,tid_b,tid_c;</p><p> int err;</p><p> err = pthread_create(&tid_a,NULL,thread_a,(void *)&tid_a);</p><p> if(err < 0)</p><p> {</p><p> perror("pthread_create thread_a");</p><p> }</p><p> printf("create tid_a = %u/n",tid_a);</p><p> err = pthread_create(&tid_b,NULL,thread_b,(void *)&tid_b);</p><p> if(err < 0)</p><p> {</p><p> perror("pthread_create thread_b");</p><p> }</p><p> printf("create tid_b = %u/n",tid_b);</p><p> err = pthread_create(&tid_c,NULL,thread_c,(void *)&tid_c);</p><p> if(err < 0)</p><p> {</p><p> perror("pthread_create thread_c");</p><p> }</p><p> printf("create tid_c = %u/n",tid_c);</p><p> sleep(5);</p><p> if(pthread_cancel(tid_a) != 0)</p><p> {</p><p> perror("pthread_cancel tid_a");</p><p> }</p><p> sleep(5);</p><p> if(pthread_cancel(tid_b) != 0)</p><p> {</p><p> perror("pthread_cancel tid_b");</p><p> }</p><p> sleep(5);</p><p> if(pthread_cancel(tid_c) != 0)</p><p> {</p><p> perror("pthread_cancel tid_c");</p><p> }</p><p> sleep(30);</p><p> printf("the main close/n");</p><p> return 0;</p><p>}<br />