在pthread库中有取消点的概念。 pthread取消点可能会中止大多数可能阻止执行时间较长(或等待某些资源...)的系统功能。
[猜想某些数据受条件变量保护,这些条件变量在线程中执行,就像下面的伪代码一样。该线程具有安装程序清除过程,以防对此线程发出取消请求。
THREAD_CLEANUP_PROC {
UNLOCK(mutex) // Is this unlock required?
}
THREAD_PROC {
SET THREAD_CLEANUP = THREAD_CLEANUP_PROC
LOOP {
LOCK(mutex)
WHILE (condition == false) {
condition.WAIT(mutex) // wait interrupted, cancel point is called
}
// ... we have the lock
UNLOCK(mutex)
condition.NOTIFY_ALL()
read(descriptor); // wait for some data on a file descriptor while lock is not acquired
}
}
如果有人在等待条件变量的同时取消线程(pthread_cancel()),则有关pthread_cond_wait
的文档说该线程在获取锁的过程中被解除阻塞,并在线程结束之前开始执行清除处理程序。
我是不是真的由清理处理程序负责解锁该锁(互斥锁?如果像我的示例一样,还有另一种阻塞方法,例如read
,它在等待数据时阻塞但没有获取锁,该怎么办?在这种情况下,read
也将被解锁,并且像以前一样调用清除处理程序。仅这次,清理处理程序不得解锁互斥锁。我对么。如果是这样,处理这种情况的最佳方法是什么?是否有应遵循的共同概念?
线程取消是混乱的。一般来说,您不应该这样做。
在pthread库中有取消点的概念。
是
[大多数可能阻止执行时间更长的系统功能(或等待某些资源...)可能会被pthread取消点中止。
不完全是。许多功能,例如您描述are取消点。具有“延迟”取消类型的线程在调用作为取消点的函数(如果当前可取消并且有取消请求待处理)时将中止。这并不意味着可以通过取消线程来中断此类功能。具有“异步”取消功能的线程可以随时或多或少地被取消,包括在阻止长时间运行的任务时,但是在这种情况下取消点是无关紧要的。
如果有人在等待条件变量的同时取消线程(pthread_cancel()),则有关
pthread_cond_wait
的文档说该线程在获取锁的过程中被解除阻塞,并在线程结束之前开始执行清除处理程序。
是,只要线程具有“延迟”取消类型。
我是不是真的清理程序现在负责解锁该锁(互斥锁?
是。在这种情况下,线程在开始取消过程时会将互斥锁保持锁定状态。如果它在终止之前没有解锁互斥锁,那么至少您会感到麻烦。某些类型的互斥锁(受pthread支持)可以提供一种从这种情况中恢复的方法,但是您最好避免这种情况。
如果-在我的示例中-还有另一种阻止方法,例如在等待数据但没有获取锁的情况下阻止读取的读取?在这种情况下,读取也会被解除阻塞,并且像以前一样调用清除处理程序。仅这次,清理处理程序不得解锁互斥锁。我正确吗?
同样,互斥量有多种类型,并且情况可能会因您使用的情况而异,但是到目前为止,最佳选择是仔细避免任何线程尝试解锁未锁定的互斥量。
如果是这样,处理这种情况的最佳方法是什么?
处理这种情况的最佳方法是首先避免这种情况。不要使用线程取消,尤其是对于容易出现这种问题的线程,这实际上是很常见的。
相反,请谨慎地编写多线程程序,以为您提供及时关闭线程或整个程序的替代方法。有很多这样的技术,超出了我在SO答案中可以合理概括的范围。