C 等待条件变量时,取消点清理需要解锁互斥锁吗?
在pthread库中有取消点的概念。pthread取消点可以中止可能阻塞执行更长时间(或等待某些resources…)的大多数系统函数 假设有一些数据受条件变量保护,该变量在线程中执行,如下面的伪代码所示。此线程有一个设置清理过程,在向该线程发出取消请求时调用该过程C 等待条件变量时,取消点清理需要解锁互斥锁吗?,c,pthreads,locking,condition-variable,code-cleanup,C,Pthreads,Locking,Condition Variable,Code Cleanup,在pthread库中有取消点的概念。pthread取消点可以中止可能阻塞执行更长时间(或等待某些resources…)的大多数系统函数 假设有一些数据受条件变量保护,该变量在线程中执行,如下面的伪代码所示。此线程有一个设置清理过程,在向该线程发出取消请求时调用该过程 THREAD_CLEANUP_PROC { UNLOCK(mutex) // Is this unlock required? } THREAD_PROC { SET THREAD_CLEANUP = THREAD
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取消点可以中止可能阻塞执行更长时间(或等待某些resources…)的大多数系统函数
不完全是。您描述的许多功能都是取消点。具有“延迟”取消类型的线程在调用作为取消点的函数时将中止,前提是该函数当前可取消并且有一个挂起的取消请求。这并不意味着这样的函数可以被线程取消中断。具有“异步”取消的线程可以在任何时候或多或少地取消,包括在阻塞长时间运行的任务时,但在这种情况下取消点是不相关的
如果有人在等待条件变量时取消线程(pthread_cancel()),那么关于pthread_cond_wait
的文档会说,线程在获取锁时会被解除阻止,并在线程结束之前开始执行清理处理程序
是,前提是线程具有“延迟”取消类型
清理处理程序现在负责解锁该锁(互斥锁),这是真的吗
对。在这种情况下,线程在开始其取消过程时保持互斥锁锁定。如果它在终止前没有解锁互斥锁,那么至少你会遇到一个大麻烦。某些类型的互斥体(由pthreads支持)可能提供了一种从这种情况中恢复的方法,但最好避免这种情况
如果有另一种阻塞方法,比如read,在等待数据时阻塞,但不获取锁,会怎么样?在这种情况下,读取也会被取消阻止,清理处理程序会像以前一样被调用。只有这一次清理处理程序才不会解锁互斥锁。我说得对吗
同样,有各种类型的互斥体,情况可能会因您使用的不同而有所不同,但到目前为止,最好的选择是小心避免任何线程试图解锁未锁定的互斥体
如果是,处理这种情况的最佳方法是什么
处理这种情况的最好办法是首先避免它。不要使用线程取消,特别是对于容易发生此类问题的线程,这些问题实际上很常见
相反,请仔细编写多线程程序,以便为自己提供及时关闭线程或整个程序的替代方法。有一大堆这样的技术,我无法在一个SO的答案中合理地总结。线程取消很麻烦。一般来说,你不应该这样做 在pthread库中有取消点的概念 对 pthread取消点可以中止可能阻塞执行更长时间(或等待某些resources…)的大多数系统函数 不完全是。您描述的许多功能都是取消点。具有“延迟”取消类型的线程在调用作为取消点的函数时将中止,前提是该函数当前可取消并且有一个挂起的取消请求。这并不意味着这样的函数可以被线程取消中断。具有“异步”取消的线程可以在任何时候或多或少地取消,包括在阻塞长时间运行的任务时,但在这种情况下取消点是不相关的 如果有人在等待条件变量时取消线程(pthread_cancel()),那么关于
pthread_cond_wait
的文档会说,线程在获取锁时会被解除阻止,并在线程结束之前开始执行清理处理程序
是,前提是线程具有“延迟”取消类型
清理处理程序现在负责解锁该锁(互斥锁),这是真的吗
对。在这种情况下,线程在开始其取消过程时保持互斥锁锁定。如果它在终止前没有解锁互斥锁,那么至少你会遇到一个大麻烦。某些类型的互斥体(由pthreads支持)可能提供了一种从这种情况中恢复的方法,但最好避免这种情况
如果有另一种阻塞方法,比如read,在等待数据时阻塞,但不获取锁,会怎么样?在这种情况下,读取也会被取消阻止,清理处理程序会像以前一样被调用。只有这一次清理处理程序才不会解锁互斥锁。我说得对吗
<
THREAD_CLEANUP_PROC {
UNLOCK(mutex) // Is this unlock required? YES
}
THREAD_PROC {
LOOP {
LOCK(mutex)
SET THREAD_CLEANUP_PUSH = THREAD_CLEANUP_PROC // After adquire the lock
WHILE (condition == false) {
condition.WAIT(mutex) // wait interrupted, cancel point is called
}
// ... we have the lock
THEAD_CLEANUP_POP(1) // This unlock the mutex and remove the cleanup
// UNLOCK(mutex)
condition.NOTIFY_ALL()
read(descriptor); // wait for some data on a file descriptor while lock is not acquired
}
}