我有 2 个进程(A、B)共享相同的互斥锁(使用 WaitForSingleObject/ReleaseMutex 调用)。一切正常,但是当进程 A 崩溃时,进程 B 正在愉快地嗡嗡作响。当我重新启动进程 A 时,会出现死锁。
更深入的调查显示,在进程 A 崩溃后,进程 B 可以成功调用 ReleaseMutex() 两次。
我的解释:进程 A 崩溃后,互斥锁仍然被锁定,但互斥锁的所有权很容易转移到进程 B(这是一个错误)。这就是为什么它愉快地嗡嗡作响,调用 WaitForSingleObject(获得 WAIT_OBJECT_0 作为返回)和 ReleaseMutex(作为返回获得 TRUE)。
是否可以使用类似于互斥锁的命名同步原语,以便进程 A 中的崩溃将释放互斥锁?
一种解决方案是使用 SEH 并捕获崩溃并释放互斥锁,但我真的希望 Windows 有一个健壮的原语,不会像进程崩溃时那样死锁。
最佳答案
关于互斥锁在 Windows 上的工作方式,您必须在此处做出一些基本假设:
所以你可以根据你的观察得出结论。当 A 崩溃时,互斥锁没有任何 react ,B 仍然有一个句柄。 B 可以注意到 A 崩溃的唯一可能方法是当 A 在它拥有互斥锁时崩溃。发生这种情况的几率非常低,而且很容易观察到,因为 B 会死锁。更有可能的是 B 会很高兴地继续前进,因为它现在完全不受阻碍,没有其他人会再获得互斥锁。
此外,当 A 重新开始时的死锁证明了您已经知道的事情:B 由于某种原因永久拥有互斥锁。可能是因为它递归地获取了互斥锁。您知道这一点是因为您注意到必须两次调用 ReleaseMutex。这是您需要修复的错误。
您需要保护自己免受兄弟进程崩溃的影响,并且需要为此编写显式代码。对同级调用 OpenProcess 以获取进程对象的句柄。当进程终止时,句柄上的 WaitForSingleObject 调用将完成。
关于winapi - 进程崩溃时未释放 Win32 命名互斥锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14985247/