linux程序設計——取消一個線程(第十二章)

12.7    取消一個線程

有時,想讓一個線程可以要求還有一個線程終止,就像給它發送一個信號同樣。

線程有方法可以作到這一點,與與信號處理同樣。線程可以被要求終止時改變其行爲。
pthread_cancel是用於請求一個線程終止的函數
函數

#inlude <pthread.h>
int pthread_cancel(pthread_t thread);
這個函數提供一個線程標識符就可以發送請求來取消它。
線程可以用 pthread_setcancelstate設置線程的取消狀態
#include <pthread.h>
int pthread_setcancelstate(int state, int *oldstate);
第一個參數的取值可以是PTHREAD_CANCEL_ENABLE,這個值贊成線程接收取消請求;或者是PTHREAD_CANCEL_DISABLE,它的做用是忽略取消請求。oldstate指針用於獲取先前的取消狀態。
假設取消請求被接受了,線程就可以進入第二個控制層次,用 pthread_setcanceltype設置取消類型
#include <pthread.h>
int pthread_setcanceltype(int type, int *oldtype);
type參數可以有兩種取值:一個是PTHREAD_CANCEL_ASYNCHRONOUR,它將使得在接收到取消請求後立刻採取行動;還有一個是PTHREAD_CANCEL_DEFERRED,它將使得在接受到取消請求後,一直等待直到線程運行下述函數之中的一個才採取行動。詳細是函數pthread_join,pthread_cond_wait,pthread_cond_timedwait,pthread_testcancel,sem_wait或sigwait.
編敲代碼thread7.c,主線程向它建立的線程發送一個取消請求。


/*************************************************************************
 > File Name:    thread7.c
 > Description:  thread7.c程序在主線程中向它建立的新線程發送一個取消請求
 > Author:       Liubingbing
 > Created Time: 2015/7/7 9:58:40
 > Other:        thread7.c程序中新線程的調用函數中分別需要設置新線程的取消狀態和取消類型
 ************************************************************************/

#include<stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>

void *thread_function(void *arg);

int main(){
	int res;
	pthread_t a_thread;
	void *thread_result;
	/* pthread_create函數建立新線程,新線程標識符保存在a_thread。新線程調用的函數爲thread_function,函數的參數爲NULL */
	res = pthread_create(&a_thread, NULL, thread_function, NULL);
	if (res != 0) {
		perror("Thread creation failed");
		exit(EXIT_FAILURE);
	}

	sleep(3);
	printf("Canceling thread...\n");
	/* pthread_cancel函數請求線程a_thread終止 */
	res = pthread_cancel(a_thread);
	if (res != 0) {
		perror("Thread cancelation failed");
		exit(EXIT_FAILURE);
	}
	printf("Waiting for thread to finish...\n");
	/* pthread_join等待線程a_thread與主線程又一次合併 */
	res = pthread_join(a_thread, &thread_result);
	if (res != 0) {
		perror("Thread join failed");
		exit(EXIT_FAILURE);
	}
	exit(EXIT_SUCCESS);
}

void *thread_function(void *arg) {
	int i, res;
	/* pthread_setcancelstate函數設置線程的取消狀態,PTHREAD_CANCEL_ENABLE贊成線程接收取消請求。PTHREAD_CANCEL_DISABLE忽略取消請求 */
	res = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
	if (res != 0) {
		perror("Thread pthread_setcancelstate failed");
		exit(EXIT_FAILURE);
	}
	/* pthread_setcanceltype函數設置線程的取消類型,PTHREAD_CANCEL_DEFERRED將使得在接收到取消請求後。一直等待直到線程運行某個函數(如pthread_join)以後才採取行動 */
	res = pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
	if (res != 0) {
		perror("Thread pthread_setcanceltype failed");
		exit(EXIT_FAILURE);
	}
	printf("thread_function is running\n");
	for (i = 0; i < 10; i++){
		printf("Thread is still running (%d)...\n", i);
		sleep(1);
	}
	pthread_exit(0);
}
以一般的方法建立新線程後,主線程休眠一下子(好讓新線程有時間開始運行),而後發送一個取消請求。例如如下所看到的:
sleep(3);
printf("Canceling thread...\n");
res = pthread_cancel(a_thread);
在新建立的線程中。首先將取消狀態設置爲贊成取消,例如如下所看到的:
res = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
而後將取消類型設置爲延遲取消,例如如下所看到的:
res = pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
最後。線程在循環中等待被取消,例如如下所看到的:
for (i = 0; i < 10; i++) {
    printf("Thread is still running (%d)...\n", i);
    sleep(1);
}
相關文章
相關標籤/搜索