确定Windows线程是否在临界区或类似的?

时间:2015-09-03 16:11:51

标签: c++ multithreading winapi critical-section

所以我们有一个断言引擎。

它的作用是创建一个断言辅助线程,挂起每个其他线程,然后在帮助程序线程中弹出一些交互式UI,以便与用户讨论断言失败。 (我们暂停其他线程,因为我们想要断言断言时程序状态的快照,我们不希望其他线程前进)。

大部分时间都很好。

一小部分时间,其中一个挂起的线程持有一个锁 - 通常是调试堆关键部分 - 并且断言辅助线程在下一次分配时阻塞(这很难避免)。

我可以通过两种方式看到这一点。首先,取消进程内断言处理(让它启动一个进程外断言对话框,并使用IPC来回通信)。这样我们可以在没有堆分配的情况下管理该通信。也许

这是一堆工作,因为这意味着我们必须将进程内堆栈行走代码移出进程等。

我们现在正在尝试的方法是添加一个看门狗线程。它注意到断言辅助线程是否未能取得进展(可能是发送定时器消息失败,可能其指令计数器停止移动;无关的实现细节)。

当它检测到这种情况时,它会尝试打破僵局。

我们当前的方法是基本上随机获取线程,将它们唤醒,然后再次挂起它们,直到我们从assert helper线程中检测到进度。这是......随意而缓慢。

为了更快地选择正确的线程,我想确定给定的Windows线程当前是否包含一个关键部分(以及其他同步原语)。然后我们可以先尝试这些线程。

那么,有没有办法确定Windows线程暂停时是否持有CriticalSection?

1 个答案:

答案 0 :(得分:2)

我认为没有一种记录方法可以判断一个帖子是否在一个关键部分,如果存在,我认为这不是解决问题的正确方法。

但是要回答这个问题,你可以查看CRITICAL_SECTION数据结构,看看拥有它的线程的句柄。这并没有直接回答这个问题,“这个线程是否在任何关键部分内?”但它确实让你回答:“这个线程是否在这个关键部分?”至少在CRITICAL_SECTION的一些关键实现细节发生变化之前。

对于您的实际问题,我会问断言引擎给出的好处是,当断言失败时,通过附加调试器不能更好地处理。调试器是外部的,绕过任何死锁,并且已经知道如何遍历堆栈,因此您不必重新实现它。