12

一些背景:

我有一个依赖于第三方硬件和闭源驱动程序的应用程序。驱动程序当前有一个错误,导致设备在随机时间后停止响应。这是由驱动程序中明显的死锁引起的,并中断了我的应用程序的正常运行,该应用程序处于始终在线的 24/7 高度可见的环境中。

我发现将 GDB 附加到进程,并立即从进程中分离 GDB 会导致设备恢复功能。这是我第一次表明驱动程序本身存在线程锁定问题。有某种竞争条件会导致死锁。附加 GDB 显然会导致一些线程重新洗牌,并可能将它们推出等待状态,导致它们重新评估它们的条件,从而打破死锁。

问题:

我的问题很简单:是否有一个干净的等待应用程序触发程序中的所有线程来中断它们的等待状态?肯定有效的一件事(至少在我的实现中)是发送一个 SIGSTOP,然后立即从另一个进程(即来自 bash)发送一个 SIGCONT:

kill -19 `cat /var/run/mypidfile` ; kill -18 `cat /var/run/mypidfile`

这会在过程中触发虚假唤醒,一切都恢复生机。

我希望有一种智能方法可以触发我进程中所有线程的虚假唤醒。思考pthread_cond_broadcast(...)但无法访问正在等待的实际条件变量。

这是可能的,还是依赖像kill我唯一的方法这样的程序?

4

1 回答 1

5

你现在做的方式可能是最正确和最简单的。内核中没有“唤醒给定进程中所有等待的 futexes”操作,这是您更直接地实现此目的所需要的。

请注意,如果唤醒失败的“死锁”在pthread_cond_wait但用信号中断它以打破死锁,则该错误不能在应用程序中;它实际上必须在 pthread 条件变量中执行。glibc 在其条件变量实现中已知未修复的错误;请参阅http://sourceware.org/bugzilla/show_bug.cgi?id=13165和相关的错误报告。但是,您可能已经找到了一个新的,因为我认为现有的已知的不能通过用信号中断 futex 等待来修复。如果您可以将此错误报告给 glibc 错误跟踪器,那将非常有帮助。

于 2012-12-26T23:22:33.473 回答