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標准所要求的目標。

#include <stdio.h> #include <unistd.h> #include <pthread.h> long long int count=0; void *func(void *param) { printf("thread begin...\n"); while (1) count++; printf("thread end...\n"); } int main(int argc, char *argv[]) { int i; pthread_t thrid; // start thread if (pthread_create(&thrid, NULL, func, NULL)) { printf("pthread_create error\n"); return -1; } // sleep for (i=0; i<5; i++) { sleep(1); printf("count=%lld\n", count); } // pthread cancel test if (!pthread_cancel(thrid)) printf( "pthread_cancel OK\n" ); for (i=0; i<5; i++) { sleep(1); printf("count=%lld\n", count); } return 0; } 執行結果 # ./a.out thread begin... count=53036914 count=92041663 count=143461789 count=196571043 count=244058852 pthread_cancel OK count=289247195 count=342442101 count=394954240 count=434139043 count=487356583

台南小新 發表在 痞客邦 PIXNET 留言(0) 人氣()