某些背景:
我有一个依赖第三方硬件和闭源驱动程序的应用程序。驱动程序当前有一个错误导致设备在一段随机时间后停止响应。这是由于驱动程序中存在明显的死锁并中断了我的应用程序的正常运行,这是一个始终在24/7高度可见的环境。
我发现将GDB附加到进程,并立即从进程中分离GDB会导致设备恢复功能。这是我第一次表明驱动程序本身存在线程锁定问题。存在某种导致僵局的竞争条件。附加GDB显然会导致一些线程重新调整,并可能使它们退出等待状态,导致它们重新评估它们的状态,从而打破僵局。
问题:
我的问题很简单:是否有一个干净的等待应用程序触发程序中的所有线程来中断其等待状态?确实有效的一件事(至少在我的实现上)是发送一个SIGSTOP,紧接着是来自另一个进程的SIGCONT(即来自bash):
kill -19 `cat /var/run/mypidfile` ; kill -18 `cat /var/run/mypidfile`
这会在整个过程中触发虚假的唤醒,一切都恢复了生机。
我希望有一种智能方法可以触发我进程中所有线程的虚假唤醒。想想pthread_cond_broadcast(...)
,但无法访问等待的实际条件变量。
这是可能的,还是依赖于kill
这样的程序我的唯一方法?
答案 0 :(得分:5)
你现在这样做的方式可能是最正确和最简单的。在内核中没有“唤醒所有在给定进程中等待的futex”操作,这是你需要更直接地实现这一点。
请注意,如果失败唤醒“死锁”在pthread_cond_wait
中,但是在信号中断的情况下突破了死锁,则该错误不在应用程序中;它实际上必须在pthread条件变量的实现中。 glibc在其条件变量实现中已经知道了未修复的错误;请参阅http://sourceware.org/bugzilla/show_bug.cgi?id=13165和相关的错误报告。但是,你可能找到了一个新的,因为我不认为可以通过突破futex等待信号来修复现有已知的那些。如果您可以将此错误报告给glibc bug跟踪器,那将非常有用。