2. pthreads特征综述 |
对于线索编程,pthreads介绍可撤消性的概念。撤消是一个选项,当所有相关线索集的操作是不要求的或者不必要时,使用此选项。最好的求助,是简单地撤消所有进程动作,恢复事件到一致的状态,并且返回起始指针。一个例子是异步地产生撤消条件,例如用户请求撤消一些正在运行的应用程序。另一个例子完成由许多线索承担的任务。这些线索之一可以最终地完成此任务,同时其它线索继续操作。由于它们在此点服务没有目的,应该撤消其它线索。
在执行撤消中,存在危险。大多数情况,它们适当地处理正在恢复的不变量,而且释放共享资源。如果不小心撤消某些线索,它会在上锁状态留下一个交互锁,从而导致死锁条件。否则它会留下一个已分配的无识别意义的内存区,因此无法释放它。
pthreads说明一个撤消接口,此接口可编程地允许或者禁止撤消。它也允许撤消句柄的范围,此句柄提供清除服务,使得他们确定何时以及在哪里打算操作。
撤消可以在三种不同的情况下发生。它们可以发生:
在所有的情况,必须注意将资源和状态恢复到与初始点相一致的条件。
调用带有一个线索ID作为参数的函数pthread_cancel(),会影响一个撤消。怎样对待一个撤消请求,依赖于目标线索的状态。两个函数,pthread_setcancelstate()和pthread_setcanceltype()决定了那个状态。pthread_setcanceltype()可以将调用线索的状态设置为PTHREAD-CANCEL-DEFERRED或者PTHREAD-CANCEL-ASYNCHRONOUS。pthread_setcancelstate()将调用线索的状态设置为PTHREAD-CANCEL-ENABLE或者PTHREAD-CANCEL-DISABLE。
如果撤消目标的状态是PTHREAD-CANCEL-DISABLE,那么所有对那个目标的撤消请求保持挂起。如果状态设置为PTHREAD-CANCEL-ENABLE,那么撤消行为依赖于某种撤消类型。如果撤消类型是PTHREAD-CANCEL-ASYNCHRONOUS,接受一个pthread_cancel()调用,会导致一个立即的撤消。如果,另一方面,撤消类型是PTHREAD-CANCEL-DEFERRED,那么直到线索达到一个撤消点时才发生撤消。
通过插入函数调用pthread_testcancel(),来在线索中建立一个撤消点。当此函数执行时,如果挂起一个撤消,那么pthread_testcancel()将不返回。否则,它没有影响。
除了可编程地决定pthread_testcancel()调用外,pthreads标准说明了许多撤消点。这些包括等待在pthread_cond_timedwait()和pthread_cond_wait()上的线索、等待在pthread_join()中的另一线索结束的线索、阻塞在sigwait()上的线索。也有许多担当撤消点的标准库调用。通常存在一些函数,线索会在它上面阻塞。
为了恢复条件到与起始点相一致的状态,例如,清除已分配的资源和恢复不变量,pthreads说明了清除句柄的使用。两个函数,pthread_cleanup_push()和pthread_cleanup_pop(),用于管理句柄。pthread_cleanup_push()将一个清除句柄压到一个清除堆栈(FIFO)上。pthread_cleanup_pop()将其从堆栈中弹出。
如果用非零的参数调用pthread_cleanup_pop(),那么执行从堆栈中弹出的句柄;否则移走和丢弃它。如果线索明显地暗含调用pthread_exit(),或者线索接受一个撤消请求,那么用非零的参数有效地调用pthread_cleanup_pop()。
调用点的摆放和调用句柄的影响,必须基于对应用程序的理解。交互锁明显不是一个撤消点,而且仅应保持在最小重要的时间。
异步撤消点的区域应该限制到没有外部相关的序列,此相关会导致悬挂资源或者未解决的状态条件。当从一些替代的、嵌套的撤消状态中返回时,应该注意恢复撤消状态。接口提供了方便这种恢复的特征。pthread_setcancelstate()在所引用的变量中保留当前的撤消状态;pthread_setcanceltype()以同样方式保留当前的撤消状态。
Copyright: NPACT |