在线程完成之前终止它称为线程取消。例如,如果多个线程同时在数据库中搜索,而一个线程返回结果,则其余线程可能会被取消。当用户按下Web浏览器上的按钮阻止网页进一步加载时,可能会发生另一种情况。通常,网页使用多个线程来加载-每个图像都在单独的线程中加载。当用户在浏览器上按下停止按钮时,将取消加载该页面的所有线程。通常将要取消的线程称为目标线程。在两种不同情况下可能会取消目标线程-
异步取消-一个线程立即终止目标线程。
延迟取消-目标线程定期检查是否应终止,从而有机会按顺序终止自身。
取消的困难发生在以下情况:将资源分配给已取消的线程,或者在更新数据的过程中线程与其他线程共享时取消了线程。对于异步取消,这尤其麻烦。很多时候,操作系统将从已取消的线程中回收系统资源,但不会回收所有资源。因此,异步取消线程可能不会释放必要的系统范围的资源。相反,在延迟取消的情况下,一个线程指示要取消目标线程,但是仅在目标线程检查了一个标志以确定是否应取消它之后,才会发生取消。可以在线程可以安全取消的位置执行此检查。在Pthreads中,cancel()
方法。目标线程的标识符作为参数传递给函数。以下代码说明了创建然后取消线程的过程-
pthread t tid; /* create the thread */ pthread create(&tid, 0, worker, NULL); … /* cancel the thread */ pthread cancel(tid);
但是,调用pthreadcancel()
表示仅请求取消目标线程。实际的取消取决于目标线程如何设置以处理请求。Pthreads支持三种取消模式。每种模式都定义为状态和类型,如下表所示。它的取消状态和类型可以由线程使用API设置。
模式 | 州 | 类型 |
---|---|---|
关 | 残障人士 | -- |
递延 | 已启用 | 递延 |
异步 | 已启用 | 异步 |
如表所示,Pthreads允许线程禁用或启用取消。显然,如果禁用取消,则无法取消线程。但是,取消请求仍处于待处理状态,因此线程可以稍后启用取消并响应该请求。默认取消类型为延迟取消。在此,仅当线程到达取消点时才发生取消。建立取消点的一种技术是调用pthreadtestcancel()
函数。如果发现取消请求待处理,则调用称为清除处理程序的功能。在终止线程之前,此函数允许释放线程可能获取的任何资源。以下代码说明了线程如何使用延迟取消来响应取消请求-
while (1){ /* do some work for a while */ /* ... */ /* check if there is a cancellation request */ pthread testcancel(); }