Linux執行緒取消
Linux執行緒可以取消其他執行緒,被取消的執行緒會被退出
執行緒本身可以設定不被其他執行緒取消
相關函式
int pthread_cancel(pthread_t thread); //同一程序的執行緒取消其他執行緒
int pthread_setcancelstate(int state, int *oldstate);//設定執行緒取消
int pthread_setcanceltype(int type, int *oldtype);//在還沒到達取消點時,可以通過這個修改取消型別
void pthread_testcancel(void); //自己新增取消點
執行緒 state
PTHREAD_CANCEL_ENABLE 執行緒是可取消的,這是所有新執行緒的預設取消狀態 PTHREAD_CANCEL_DISABLE 執行緒是不可取消的,如果接收到取消請求,它將被阻塞,直到可以celability啟用。
執行緒啟動時預設的可取消狀態是PTHREAD CANCEL-ENABLE。
當狀態設為PTHREAD CANCEL-DISABLE時,對pthread_cancel的呼叫並不會殺死執行緒。
相反,取消請求對這個執行緒來說還處於掛起狀態,
當取消狀態再次變為PTHREAD-CANCEL-ENABLE時,執行緒將在下一個取消點上對所有掛起的取消請求進行處理。
操作步驟:
- 把執行緒A的state設定為PTHREAD CANCEL-DISABLE
- 執行緒B向執行緒A傳送取消訊號
- 執行緒A收到取消訊號,阻塞該訊號
- 把執行緒A的state設定為PTHREAD-CANCEL-ENABLE
- 執行緒A執行取消訊號,中止執行緒
注意:
這裡恢復執行緒可以取消後,不是一恢復馬上就把執行緒中止,而是執行到下面的函式後才可以取消,
我們自己也可以新增取消點,用void pthread_testcancel(void); 這裡的函式沒列舉全
把執行緒狀態設定為PTHREAD CANCEL-DISABLE的例項程式碼:
#include <pthread.h> #include <stdio.h> #include <string.h> pthread_t tid1, tid2, tid3; void* th_reader1(void *p) { int i = 1; int oldstate = -1; pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); for(; i <= 5; i++) { printf("func[%s]: 第 %d 秒\n", __FUNCTION__, i); sleep(1); } pthread_exit( (void *)0 ); } int main() { void *ret1, *ret2, *ret3; printf("start thread reader 1\n"); pthread_create(&tid2, NULL, th_reader1, NULL); //建立 讀 執行緒1 sleep(2); pthread_cancel(tid2); //傳送取消訊號 pthread_join(tid2, &ret2); return 0; }
執行結果:
# ./a.out start thread reader 1 func[th_reader1]: 第 1 秒 func[th_reader1]: 第 2 秒 func[th_reader1]: 第 3 秒 func[th_reader1]: 第 4 秒 func[th_reader1]: 第 5 秒
把執行緒狀態設定為PTHREAD CANCEL-DISABLE後,再設定為PTHREAD-CANCEL-ENABLE的例項程式碼:
#include <pthread.h>
#include <stdio.h>
#include <string.h>
pthread_t tid1, tid2, tid3;
void* th_reader1(void *p)
{
int i = 1;
int oldstate = -1;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
for(; i <= 5; i++)
{
printf("func[%s]: 第 %d 秒\n", __FUNCTION__, i);
sleep(1);
if(4 == i)
{
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
printf("thread cancel PTHREAD-CANCEL-ENABLE \n");
pthread_testcancel();
}
}
pthread_exit( (void *)0 );
}
int main()
{
void *ret1, *ret2, *ret3;
printf("start thread reader 1\n");
pthread_create(&tid2, NULL, th_reader1, NULL); //建立 讀 執行緒1
sleep(2);
pthread_cancel(tid2);//傳送取消訊號
pthread_join(tid2, &ret2);
return 0;
}
執行結果:
# ./a.out start thread reader 1 func[th_reader1]: 第 1 秒 func[th_reader1]: 第 2 秒 func[th_reader1]: 第 3 秒 func[th_reader1]: 第 4 秒 thread cancel PTHREAD-CANCEL-ENABLE