Ads 468x60px

##EasyReadMore##

05 5月, 2016

[C] linux pthread cancel



寫法:

  1. #include <stdio.h>  
  2. #include <unistd.h>  
  3. #include <pthread.h>  
  4.   
  5. long long int count=0;  
  6.   
  7. void *func(void *param)  
  8. {  
  9. //  pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);  
  10.     pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);  
  11.     printf("thread begin...\n");  
  12.     while (1) count++;  
  13.     printf("thread end...\n");  
  14. }  
  15.   
  16. int main(int argc, char *argv[])  
  17. {  
  18.     int i;  
  19.     pthread_t thrid;  
  20.   
  21.     // start thread  
  22.     if (pthread_create(&thrid, NULL, func, NULL)) {  
  23.         printf("pthread_create error\n");  
  24.         return -1;  
  25.     }  
  26.   
  27.     // sleep  
  28.     for (i=0; i<5; i++) {  
  29.         sleep(1);  
  30.         printf("count=%lld\n", count);  
  31.     }  
  32.   
  33.     // pthread cancel test  
  34.     if (!pthread_cancel(thrid)) printf( "pthread_cancel OK\n" );  
  35.     for (i=0; i<5; i++) {  
  36.         sleep(1);  
  37.         printf("count=%lld\n", count);  
  38.     }  
  39.   
  40.     return 0;  
  41. }  


結果:


thread begin...
count=468583606
count=934268310
count=1416636062
count=1892030447
count=2375236200
pthread_cancel OK
count=2375236200
count=2375236200
count=2375236200
count=2375236200
count=2375236200

編譯:
記得加上 -lpthread

說明:


int pthread_setcancelstate(int state, int *oldstate);
作用:設置可取消的狀態
PTHREAD_CANCEL_ENABLE: 線程取消請求將被傳遞。(預設值)
PTHREAD_CANCEL_DISABLE: 代表針對目標線程的取消請求將處於未决狀態(未決代表為不處理,但請求依然存在)。除非線程修改自己的狀態,否則不會被取消。
int pthread_setcanceltype(int state, int *oldstate);
作用:設定線程接收到CANCEL信號的執行時間
PTHREAD_CANCEL_DEFFERED: 表示線程接收到CANCEL信號會執行到下一個取消點退出。(預設值)
PTHREAD_CANCEL_ASYCHRONOUS: 表示線程接收到CANCEL信號立即終止。

pthread_cancel 用來停止 thread 有限制,以下的程式碼根本停不了,因為有沒有 Cancellation-point。

線程取消的方法是向目標線程發送 CANCEL 信號,但如何處理 Cancel 信號則由目標線程自己決定,或者忽略、或者立即終止、或者繼續運行至 Cancellation-point(取消點),由不同的 Cancellation 狀態決定。

線程接收到 CANCEL 信號的預設處理(即pthread_create()建立線程的預設狀態)是繼續執行至取消點,也就是說設置一個 CANCELED 狀態,線程繼續執行,只有執行至 Cancellation-point 的時候才會退出。

根據POSIX標准,pthread_join()、pthread_testcancel()、pthread_cond_wait()、pthread_cond_timedwait()、sem_wait()、sigwait() 等函數以及 read()、write()、sleep()、printf() 等會引起阻塞的系統調用都是 Cancellation-point,而其他 pthread 函數都不會引起 Cancellation 動作。但是 pthread_cancel 的手冊頁聲稱,由於LinuxThread庫與C庫結合得不好,因而目前C庫函數都不是 Cancellation-point 但 CANCEL 信號會使線程從阻塞的系統調用中退出,並置 EINTR 錯誤碼,因此可以在需要作為 Cancellation-point 的系統調用前後調用 pthread_testcancel(),從而達到POSIX標准所要求的目標。

參考:

Linux pthread cancel part 1 @ 邱小新の工作筆記 :: 痞客邦 PIXNET :: - http://goo.gl/tZM42Q
Linux pthread cancel part2 @ 邱小新の工作筆記 :: 痞客邦 PIXNET :: - http://goo.gl/WW8iEW

0 意見:

張貼留言

 
Blogger Templates