首页 > 代码库 > linux程序设计——取消一个线程(第十二章)

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);
}


linux程序设计——取消一个线程(第十二章)