进程崩溃时未释放Win32命名互斥锁 [英] Win32 Named mutex not released when process crashes

查看:200
本文介绍了进程崩溃时未释放Win32命名互斥锁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有2个进程(A,B)共享同一个互斥锁(使用WaitForSingleObject/ReleaseMutex调用).一切正常,但是当进程A崩溃时,进程B会愉快地嗡嗡作响.重新启动进程A时,出现死锁.

I have 2 processes (A, B) sharing the same mutex (using WaitForSingleObject / ReleaseMutex calls). Everything works fine, but when process A crashes, process B is humming along happily. When I restart process A, there's a deadlock.

更深入的调查显示,进程B崩溃后,进程B可以成功调用两次ReleaseMutex().

Deeper investigation reveals that process B can successfully call ReleaseMutex() twice after process A crashes.

我的解释:进程A崩溃后,互斥锁仍然处于锁定状态,但是互斥锁的所有权很容易转移到进程B(这是一个错误).这就是为什么它愉快地嗡嗡作响,调用WaitForSingleObject(返回WAIT_OBJECT_0)和ReleaseMutex(返回TRUE)的原因.

My interpretation: After process A crashes, the mutex is still locked, but ownership of the mutex transfers readily to process B (which is a bug). That's why it's humming along happily, calling WaitForSingleObject (getting WAIT_OBJECT_0 in return) and ReleaseMutex (getting TRUE in return).

是否可以使用类似于Mutex的命名同步原语,使进程A中的崩溃将释放互斥锁?

Is it possible to use a named synchronization primitive similar to Mutex in such a way that a crash in process A will release the mutex?

一种解决方案是使用SEH捕获崩溃并释放互斥锁,但是我真的希望Windows具有一个健壮的原语,而不会像进程崩溃时那样死锁.

One solution is to use SEH and catch the crash and release mutex, but I really hope Windows has a robust primitive that doesn't deadlock like that on process crash.

推荐答案

您必须在此处对互斥锁在Windows上的工作方式进行一些基本假设:

Some basic assumptions you have to make here about how a mutex works on Windows:

  • 互斥锁是引用计数的操作系统对象.直到互斥锁上的最后一个句柄关闭,它才会消失
  • 在进程终止时任何未关闭的句柄都被操作系统关闭,从而减少了引用计数
  • 互斥锁是可重入,在同一线程上的互斥锁上调用WaitForSingleObject成功,并且需要用相等数量的ReleaseMutex调用来平衡
  • 当拥有互斥锁的线程在不调用ReleaseMutex的情况下终止时,
  • 拥有的互斥锁将被放弃.在这种状态下在互斥锁上调用WaitForSingleObject会生成WAIT_ABANDONED错误返回代码
  • 这绝不是操作系统中的错误.
  • a mutex is an operating system object that's reference-counted. It will not disappear until the last handle on the mutex is closed
  • any handle that's left unclosed when a process terminates is closed by the operating system, decrementing the reference count
  • a mutex is re-entrant, calling WaitForSingleObject on a mutex on the same thread succeeds and needs to be balanced with an equal number of ReleaseMutex calls
  • an owned mutex becomes abandoned when the thread that owns it terminates without calling ReleaseMutex. Calling WaitForSingleObject on a mutex in this state generates the WAIT_ABANDONED error return code
  • it is never a bug in the operating system.

因此,您可以根据自己的观察得出结论.当A崩溃时,互斥体什么都没有发生,而B仍然有一个句柄. B能够注意到A崩溃的唯一可能方法是A在拥有互斥量时崩溃.这样做的可能性很小,很容易观察到,因为B会死锁.因为现在B完全不受阻碍,所以B会很乐意继续运行,没有其他人可以再获取互斥体了.

So you can draw conclusions from this by what you observed. Nothing happens to the mutex when A crashes, B still has an handle on it. The only possible way B can notice that A crashed is when A crashed while it owned the mutex. Very low odds for that and easily observed since B will deadlock. Far more likely is that B will happily motor on since it is now completely unobstructed, nobody else is going to acquire the mutex anymore.

此外,当A重新启动时出现死锁证明您已经知道:B由于某种原因永久拥有该互斥量.可能是因为它以递归方式获取了互斥量.您之所以知道这一点,是因为您发现必须两次致电ReleaseMutex.这是您需要修复的错误.

Furthermore, a deadlock when A starts back proves something you already knew: B owns the mutex permanently for some reason. Possibly because it acquired the mutex recursively. You know this because you noticed you had to call ReleaseMutex twice. This is a bug you need to fix.

您需要保护自己免受崩溃的兄弟进程的侵害,并且需要为此编写明确的代码.在同级上调用OpenProcess以获取流程对象的句柄.进程终止时,将完成对句柄的WaitForSingleObject调用.

You'll need to protect yourself against a crashing sibling process and you need to write explicit code for that. Call OpenProcess on the sibling to obtain a handle on the process object. A WaitForSingleObject call on the handle will complete when the process terminates.

这篇关于进程崩溃时未释放Win32命名互斥锁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆