打破条件变量死锁
我遇到这样的情况:线程 1 正在等待条件变量 A ,该变量应该由线程 2 唤醒。现在线程 2 正在等待条件变量 B ,该变量应该由线程 1 唤醒。在我使用的场景中条件变量,我无法避免这样的死锁情况。我检测到循环(死锁)并终止死锁参与者的线程之一。
现在,我不确定如何简单地终止一个正在等待条件变量的线程(例如线程 1)。
将不胜感激一些指点。 谢谢
I have a situation where thread 1 is waiting on a condition variable A, which should be woken up by thread 2. Now thread 2 is waiting on a condition variable B , which should be woken up by thread 1. In the scenario I am using the condition variable, I cannot avoid such a deadlock situation. I detect cycle(deadlock) and terminate one of the threads which is a participant in the deadlock.
Now, what I am not sure is how to simply terminate a thread say thread 1 which is waiting on a condition variable.
Would be grateful for some pointers.
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
条件变量不像互斥体。我的意思是它们不仅仅可以由控制它们的单个线程使用。保护条件变量的互斥锁以这种方式处理,但仅锁定很短的时间,由线程在踢出(发出信号)条件变量后手动解锁,并由等待这样的踢出的线程自动解锁。
您可以拥有一个完全独立的线程(就像您的死锁检测器,我们将其称为线程 3),只需启动其中一个条件变量,它就会唤醒等待它的线程。
条件变量的常见用例是线程等待踢出,然后检查以确保您有工作(不要仅仅因为变量被踢出就假设有工作)。这是为了处理虚假唤醒。
一种可能性是拥有一个“全局”deadlock_occurred 标志,线程 3 在检测到死锁时设置该标志,然后让线程 3 踢出所有条件变量。
线程 1 和 2 被唤醒后应该做的第一件事是检查该标志并采取适当的操作(可能退出线程)。
您会发现,如果您构建应用程序以使线程对自己的生命周期负责,那么您会遇到更少的死锁类型的麻烦。当线程不处于适合终止的状态时,从外部终止线程太容易了。不要误会我的意思,还有其他方法可以处理它(例如使用取消点),但我经过尝试和测试的解决方案是迄今为止我发现的最简单的解决方案。
Condition variables aren't like mutexes. By that I mean they aren't only usable by a single thread controlling them. The mutex that protects the condition variable is treated that way but that's only locked for short periods of time, unlocked manually by a thread after kicking (signalling) the condition variable, and automatically by a thread waiting for such a kick.
You can have a totally separate thread (like your deadlock detector, let's call it thread 3) simply kick one of the condition variables and it will wake up the thread waiting for it.
The usual use case for condition variables is for threads to wait for the kick then check to ensure you have work anyway (don't assume there is work simply because the variable was kicked). That's to take care of spurious wake-ups.
One possibility is to have a "global" deadlock_occurred flag which thread 3 sets when it detects deadlock, then also have thread 3 kick all the condition variables.
The first thing that threads 1 and 2 should do after being woken, should be to check that flag and take appropriate action (probably exit the thread).
You'll find you get into a lot less deadlock-type trouble if you architect your applications so that threads are responsible for their own lifetime. It's too easy to externally kill threads when they're not in a state amenable to being terminated. Don't get me wrong, there are other ways to handle it (such as with cancel points), but my tried and tested solution is by far the easiest I've ever found.