1. 程式人生 > >Linux執行緒取消

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時,執行緒將在下一個取消點上對所有掛起的取消請求進行處理。

操作步驟:

  1. 把執行緒A的state設定為PTHREAD CANCEL-DISABLE
  2. 執行緒B向執行緒A傳送取消訊號
  3. 執行緒A收到取消訊號,阻塞該訊號
  4. 把執行緒A的state設定為PTHREAD-CANCEL-ENABLE
  5. 執行緒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