博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UNIX环境编程学习笔记(28)——多线程编程(三):线程的取消
阅读量:6515 次
发布时间:2019-06-24

本文共 4462 字,大约阅读时间需要 14 分钟。

lienhua34

2014-11-24

1 取消线程

pthread 提供了pthread_cancel 函数用于请求取消同一进程中的其他线程。

#include <pthread.h>

int pthread_cancel(pthread_t tid);

返回值:若成功则返回0,否则返回错误编码

pthread_cancel 调用并不会立即终止目标线程,而只是向目标线程发出取消请求。调用线程不等待目标线程终止,在默认情况下,目标线程在取消请求发出以后还是继续运行的,直到目标线程到达某个取消点。取消点是线程检查是否被取消并按照请求进行动作的一个位置。

下面我们来看个线程取消的例子。主线程创建一个新线程,新线程循环睡眠 5 秒钟然后返回 2. 而主线程在创建新线程之后睡眠 2 秒钟便调用pthread_cancel 来请求取消新线程。最后获取新线程的退出状态。

#include 
#include
#include
#include
void *my_thread(void *arg){ int i=0; printf("[new thread]: I will sleep 5 seconds.\n"); while (i < 5) { sleep(1); i = i + 1; printf("[new thread]: %d\n", i); } printf("[new thread]: exit now.\n"); return ((void *)0);}intmain(void){ int err; pthread_t tid; void *tret; err = pthread_create(&tid, NULL, my_thread, NULL); if ( err != 0) { printf("can't create thread: %s\n", strerror(err)); exit(-1); } sleep(2); printf("[main thread]: cancel new thread.\n"); err = pthread_cancel(tid); if (err != 0) { printf("can't cancel thread: %s\n", strerror(err)); exit(-1); } err = pthread_join(tid, &tret); if (err != 0) { printf("can't join with new thread: %s\n", strerror(err)); exit(-1); } else { if (PTHREAD_CANCELED == tret) { printf("new thread has been canceled.\n"); } else { printf("new thread exit code: %d\n", (int)tret); } } exit(0);}

编译该程序,生成并执行文件pthread_cancel_demo,

lienhua34:demo$ gcc -o pthread_cancel_demo -pthread pthread_cancel_demo.clienhua34:demo$ ./pthread_cancel_demo[new thread]: I will sleep 5 seconds.[new thread]: 1[main thread]: cancel new thread.new thread has been canceled.

如果某个线程响应了取消请求相当于调用了参数为PTHREAD_CANCELED的pthread_exit 函数。

2 线程取消属性

前面学习了可以通过pthread_attr_t 结构来控制线程的属性。但是有两个与线程取消的属性没有包含在pthread_attr_t 结构中,它们是可取消状态和可取消类型。

2.1 可取消状态

可取消状态属性是个使能属性,控制了线程是否要响应其他线程的取消请求。该属性可以是PTHREAD_CANCEL_ENABLE,或者是PTHREAD_CANCEL_DISABLE。线程的可取消属性默认为前者。如果设置为后者,则线程将不会响应取消请求,不过取消请求对于该线程来说处于未决状态,当可取消状态再次变为PTHREAD_CANCEL_ENABLE 时,线程将在下个取消点上对所有未决的取消请求进行处理。

线程可以通过调用pthread_setcancelstate 函数来修改其可取消状态。

#include <pthread.h>

int pthread_setcancelstate(int state, int *oldstate);

返回值:若成功则返回0,否则返回错误编号

该函数将线程的当前可取消状态设置为 state,并通过 oldstate 返回原来的可取消状态。

下面我们来看那个例子,我们在上面的pthread_cancel_demo.c 程序的新线程入口函数my_thread 的开始调用pthread_setcancelstate 函数将新线程的可取消状态设置为PTHREAD_CANCEL_DISABLE。

#include 
#include
#include
#include
void *my_thread(void *arg){ int i=0; int err; err = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); if (err != 0) { printf("[new thread]: can't set cancel state: %s\n", strerror(err)); } printf("[new thread: disable cancel state.\n"); printf("[new thread]: I will sleep 5 seconds.\n"); while (i < 5) { sleep(1); i = i + 1; printf("[new thread]: %d\n", i); } printf("[new thread]: exit now.\n"); return ((void *)0);}intmain(void){ int err; pthread_t tid; void *tret; err = pthread_create(&tid, NULL, my_thread, NULL); if ( err != 0) { printf("can't create thread: %s\n", strerror(err)); exit(-1); } sleep(2); printf("[main thread]: cancel new thread.\n"); err = pthread_cancel(tid); if (err != 0) { printf("can't cancel thread: %s\n", strerror(err)); exit(-1); } err = pthread_join(tid, &tret); if (err != 0) { printf("can't join with new thread: %s\n", strerror(err)); exit(-1); } else { if (PTHREAD_CANCELED == tret) { printf("new thread has been canceled.\n"); } else { printf("new thread exit code: %d\n", (int)tret); } } exit(0);}

编译该程序,生成并执行pthread_cancel_demo 文件,

lienhua34:demo$ gcc -o pthread_cancel_demo -pthread pthread_cancel_demo.clienhua34:demo$ ./pthread_cancel_demo[new thread: disable cancel state.[new thread]: I will sleep 5 seconds.[new thread]: 1[main thread]: cancel new thread.[new thread]: 2[new thread]: 3[new thread]: 4[new thread]: 5[new thread]: exit now.new thread exit code: 0

从上面的运行结果与前一节的运行结果对比,我们可以看出将新线程的可取消状态设置为PTHREAD_CANCEL_DISABLE 后,新线程没有响应主线程的取消请求。

2.2 可取消类型

上面所说的线程在到达某个取消点的时候会去检查一下是否被取消。这种取消类型也称为延迟取消。另外,还有一种取消类型是异步取消。当线程的取消类型为异步取消时,线程可以在任意时间被取消。

线程可以通过调用pthread_setcanceltype 来修改线程的取消类型。

#include <pthread.h>

int pthread_setcanceltype(int type, int *oldtype);

返回值:若成功则返回0,否则返回错误编号

其中type参数可以是PTHREAD_CANCEL_DEFERRED(延迟取消), 或者PTHREAD_CANCEL_ASYNCHRONOUS(异步取消)。该函数将线程的当前可取消类型设置为 type,然后将原来的可取消类型通过 oldtype 参数返回。

(done)

转载地址:http://ehafo.baihongyu.com/

你可能感兴趣的文章
经验贴 | 电梯监控的布线技巧
查看>>
唐山联通与丰南区政府签署“智慧城市”战略合作协议
查看>>
研究显示:广告拦截应用正在破坏互联网
查看>>
优云·小课堂 第八期:运维自动化的魅力
查看>>
稳定+性能+价格,阿里云发力ECS企业级产品
查看>>
写个软件来防止服务器网站CPU百分百
查看>>
智能城市里,“公共电话亭”的存在意味着什么?
查看>>
JVM分代垃圾回收策略的基础概念
查看>>
《交互式程序设计 第2版》一3.5 捕获简单用户交互行为
查看>>
安装操作系统需要注意的事项
查看>>
5G技术的5大猜想
查看>>
MongoDB 3.0(1):CentOS7 安装MongoDB 3.0服务
查看>>
别随便安装 Pokemon GO被曝藏恶意后门
查看>>
BBC即将推出Britflix流媒体服务:欲成为英国版Netflix
查看>>
让数据会思考会说话,为出海企业提供多样化数据智能解决方案
查看>>
我眼中的自动化测试框架设计要点
查看>>
FLIF:自由的无损图像格式
查看>>
《计算机系统:核心概念及软硬件实现(原书第4版)》——3.7 总结
查看>>
Google开源Inception-ResNet-v2,提升图像分类水准
查看>>
Opera 出售细节曝光:昆仑出资1.68亿美元
查看>>