2011-08-03 44 views
0

此问题源于Breaking a condition variable deadlock。许多线程可能正在等待一个条件变量,我只需要发信号通知一个特定的线程,如线程1并杀死它,因为它是一个死锁场景的参与者。有没有一种方法可以在很多方面发出一个单独的线索。在等待条件变量的许多信号中发送特定线程

会一些帮助是gratefull

感谢

的编辑;尊重尼莫的评论。我明白这是一个坏主意。但是,有没有办法做到这一点

+4

由于概率非常接近1,因此您的设计存在缺陷。你几乎肯定不希望“检测到死锁并杀死参与其中的线程之一”。你想修复你的基本设计,以防止发生死锁...... – Nemo

+0

@Nemo ...我同意你的看法。但是,在我们的特殊情况下,我们选择检测并解决死锁而不是避免死锁,因为死锁发生的可能性非常罕见。 –

+1

对不起@Juggler,但我不买这种哲学。这是软件。没有“极其罕见”的东西。只有“从不”和“越野车”。或者尤达会说,没有尝试。 – Nemo

回答

1

您可以使用延期取消点。在你的线程中,使用pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldstate);(这是默认的,但从不伤害是明确的);然后通过pthread_setcancelstate禁用取消,除了超出条件变量等待您希望取消。请确保您使用pthread_cleanup_push来设置取消清理处理程序;这与RAII不会很好地配合。

现在你可以只是pthread_cancel你的线程。按照注册的相反顺序执行取消清理处理程序,调用TLS数据析构函数,并且线程退出(不从条件变量wait中返回)。

当然,这是一个相当丑陋的设计。理想情况下,你应该避免死锁;如果这是不可能的,如果是我,我会安排一次只有一个线程阻塞单个cvar,并基于这些cvars构建更高级别(显式服务器列表)构造以处理多个服务员,同时仍然允许线程单独寻址。

+0

您能详细解释一下吗?在取消和等待条件变量之间是否没有根本的竞争条件?也就是说,你持有一个互斥量,启用取消,然后尝试等待cond var ...但是在此期间有人决定你僵持并且在你持有互斥锁的时候核武你? – Nemo

+0

@Nemo,从pthread_cond_wait手册页:“条件等待(无论是否定时)是取消点。当一个线程的可取消使能状态设置为PTHREAD_CANCEL_DEFERRED时,在条件等待期间作用于取消请求的副作用是在调用第一个取消清除处理程序之前重新获取互斥(实际上)。“因此,您的清理处理程序必须释放互斥锁。 – bdonlan

0

只需编写代码即可完成您所需的任务。没有捷径,因为条件变量不提供这种行为。所以写下吧。这没有什么困难。例如,您可以设置一个特殊标志,唤醒所有线程在条件变量上被阻塞,然后对线程进行编码以检查标志以确定是否应该返回到睡眠状态。