有两个线程属性并没有包含在pthread_attr_t结构中,它们是可取消状态和可取消类型。这两个属性影响着线程在响应pthread_cancel函数(http://www.cnblogs.com/nufangrensheng/p/3519175.html)调用时所呈现的行为。
可取消状态属性可以是PTHREAD_CANCEL_ENABLE,也可以是PTHREAD_CANCEL_DISABLE。线程可以通过调用pthread_setcancelstate修改它的可取消状态。
#include <pthread.h> int pthread_setcancelstate(int state, int *oldstate); 返回值:若成功则返回0,否则返回错误编号
pthread_setcancelstate把当前的可取消状态设置为state,把原来的可取消状态存放在由oldstate指向的内存单元中,这两步是原子操作。
pthread_cancel调用并不等待线程终止,在默认情况下,线程在取消请求发出以后还是继续运行,直到线程到达某个取消点。取消点是线程检查是否被取消并按照请求进行动作的一个位置。POSIX.1保证在线程调用表12-7中列出的任何函数时,取消点都会出现。
表12-7 POSIX.1定义的取消点
线程启动时的默认的可取消状态时PTHREAD_CANCEL_ENABLE。当状态设为PTHREAD_CANCEL_DISABLE时,对pthread_cancel的调用并不会杀死线程;相反,取消请求对这个线程来说处于未决状态。当取消状态再次变为PTHREAD_CANCEL_ENABLE时,线程将在下一个取消点上对所有未决的取消请求进行处理。
除了表12-7中列出的函数,POSIX.1还指定了表12-8中列出的函数作为可选的取消点。
表12-8 POSIX.1定义的可选取消点
如果应用程序在很长一段时间内都不会调用到表12-7或表12-8中的函数,那么可以调用phread_testcancel函数在程序中自己添加取消点。
#include <pthread.h> void pthread_testcancel(void);
调用pthread_testcancel时,如果有某个取消请求正处于未决状态,而且取消并没有置为无效,那么线程就会被取消。但是如果取消被置为无效时,pthread_testcancel调用就没有任何效果。
这里描述的默认取消类型也称为延迟取消。调用pthread_cancel以后,在线程到达取消点之前,并不会出现真正的取消。可以通过调用pthread_setcanceltype来修改取消类型。
#include <pthread.h> int pthread_setcanceltype(int type, int *oldtype); 返回值:若成功则返回0,否则返回错误编号
type参数可以是PTHREAD_CANCEL_DEFERRED,也可以是PTHREAD_CANCEL_ASYNCHRONOUS,pthread_setcanceltype函数把取消类型设置为type,把原来的取消类型返回到oldtype指向的整数单元。
异步取消与延迟取消不同,使用异步取消时,线程可以在任意时间取消,而不是非得遇到取消点才能被取消。
本篇博文内容摘自《UNIX环境高级编程》(第二版),仅作个人学习记录所用。关于本书可参考:http://www.apuebook.com/。