“安全”互斥体的处理?
我不断地从另一个进程正在写入的内存映射文件中读取数据,并使用互斥锁来同步此操作。到目前为止,在我的几次测试中,这工作得很好,但是......如果我的应用程序在获取互斥体之后和释放它之前崩溃了怎么办?即使发生此类崩溃,是否有任何方法可以保证互斥体的释放?
另外,我将如何处理其他进程的崩溃,该进程可能尚未释放互斥体?每次调用 mutex.WaitOne() 时是否需要处理 AbandonedMutexException?
现在我正在做类似的事情:
public MyState GetState()
{
MyState state = new State();
this._mutex.WaitOne();
try
{
state.X = this._mmView.ReadSingle(0);
state.Y = this._mmView.ReadSingle(4);
[..]
}
finally
{
this._mutex.ReleaseMutex();
}
return state;
}
_mmView 是我之前实例化的 MemoryMappedViewAccessor 。整个方法 GetState() 在游戏循环的每一帧中都会被调用,因此大约每隔几毫秒调用一次。
PS:另外,还有其他我没有提到的明显问题可能会失败吗?
I'm constantly reading from a memory mapped file another process is writing to and use a mutex to synchronize this operation. In my few tests so far this works just fine, but... what if my application crashes right after acquiring the mutex and before releasing it? Is there any way to guarantee a release of the mutex, even in case of such a crash?
Also how would I handle a crash of the other process, which might not have released the mutex yet? Do I need to handle AbandonedMutexException each time I call mutex.WaitOne()?
Right now I'm doing it similar to this:
public MyState GetState()
{
MyState state = new State();
this._mutex.WaitOne();
try
{
state.X = this._mmView.ReadSingle(0);
state.Y = this._mmView.ReadSingle(4);
[..]
}
finally
{
this._mutex.ReleaseMutex();
}
return state;
}
_mmView is a MemoryMappedViewAccessor I instantiated before. This whole method GetState() gets called each frame as part of a game loop, so about every few milliseconds.
PS: Also, is there any other obvious problem why this could fail, that I didn't already mention?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当进程在拥有互斥锁的情况下结束时,操作系统将自动为您释放互斥锁。通过获取互斥锁来尝试这一点,然后引发新的WhateverException() ,其他进程将继续。
AFAIK 所有同步原语都是如此
When a process ends while owning a mutex, the OS will automatically release the mutex for you. Try this out by aquiring the mutex and then
raise new WhateverException()
- the other process will carry on.The same is true for all sync primitives AFAIK
Eugen 的答案是正确的——操作系统会为你释放互斥体。现在认真思考这一事实的后果是什么:
简而言之,你担心的是错误的事情。您不应该担心如果我的互斥体永远被释放会发生什么。然后发生的最糟糕的事情是每个人都永远等待,这很悲伤,但最终用户会重新启动机器。您应该担心如果互斥体确实因为我在突变中崩溃而被释放会发生什么。在这种情况下,进程现在可能会到处崩溃,并且用户的数据将永久损坏。
首先不要陷入这种情况。问题的解决方案是取出互斥体进行写入时不要崩溃。如果您不编写崩溃的程序,那么您不必担心它,因为它不会发生。所以不要编写会崩溃的程序。
Eugen's answer is correct -- the operating system will release the mutex for you. Now think hard about what the consequences of this fact are:
In short, you are worrying about exactly the wrong thing. You shouldn't be worried about what happens if my mutex never gets released. The worst thing that happens then is everyone waits forever, which is sad, but eventually the user will reboot the machine. You should be worried about what happens if mutex does get released because I crashed halfway through a mutation. In that scenario processes will now probably be crashing all over the place and the user's data will be permanently corrupted.
Don't get into that situation in the first place. The solution to the problem is do not crash when you have taken out a mutex for writing. If you don't write programs that crash then you don't have to worry about it, because its not going to happen. So just don't write programs that ever crash.