有两个线程属性并没有包含在pthread_attr_t结构中,它们是可取消状态和可取消类型。这两个属性影响着线程在响应pthread_cancel函数调用时所呈现的行为(见11.5节)。

可取消状态属性可以是PTHREAD_CANCEL_ENABLE,也可以是PTHREAD_CANCEL_DISABLE。线程可以通过调用pthread_setcancelstate修改它的可取消状态。

#include <pthread.h>
int pthread_setcancelstate(int state, int *oldstate);
//返回值:若成功,返回0;否则,返回错误编号

pthread_setcancelstate把当前的可取消状态设置为state,把原来的可取消状态存储在由oldstate指向的内存单元,这两步是一个原子操作。

回忆11.5节,pthread_cancel调用并不等待线程终止。在默认情况下,线程在取消请求发出以后还是继续运行,直到线程到达某个取消点。取消点是线程检查它是否被取消的一个位置,如果取消了,则按照请求行事。POSIX.1保证在线程调用图12-14中列出的任何函数时,取消点都会出现。

图12-14 POSIX.1定义的取消点

线程启动时默认的可取消状态是 PTHREAD_CANCEL_ENABLE。当状态设为 PTHREAD_CANCEL_DISABLE时,对pthread_cancel的调用并不会杀死线程。相反,取消请求对这个线程来说还处于挂起状态,当取消状态再次变为PTHREAD_CANCEL_ENABLE时,线程将在下一个取消点上对所有挂起的取消请求进行处理。

除了图12-14中列出的函数,POSIX.1还指定了图12-15中列出的函数作为可选的取消点。

图12-15中列出的有些函数并没有在本书中进一步讨论,例如,处理消息分类和宽字符集的函数。

如果应用程序在很长的一段时间内都不会调用图12-14或图12-15中的函数(如数学计算领域的应用程序),那么你可以调用pthread_testcancel函数在程序中添加自己的取消点。

#include <pthread.h>
void pthread_testcancel(void);

调用pthread_testcancel时,如果有某个取消请求正处于挂起状态,而且取消并没有置为无效,那么线程就会被取消。但是,如果取消被置为无效,pthread_testcancel调用就没有任何效果了。

图12-15 POSIX.1定义的可选取消点

我们所描述的默认的取消类型也称为推迟取消。调用pthread_cancel以后,在线程到达取消点之前,并不会出现真正的取消。可以通过调用pthread_setcanceltype来修改取消类型。

#include <pthread.h>
int pthread_setcanceltype(int type, int *oldtype);
//返回值:若成功,返回0;否则,返回错误编号

pthread_setcanceltype函数把取消类型设置为type(类型参数可以是PTHREADCANCEL_DEFERRED,也可以是PTHREAD_CANCEL_ASYNCHRONOUS),把原来的取消类型返回到oldtype指向的整型单元。

异步取消与推迟取消不同,因为使用异步取消时,线程可以在任意时间撤消,不是非得遇到取消点才能被取消。

results matching ""

    No results matching ""