“安全”互斥体的处理?

发布于 2025-01-03 06:07:01 字数 735 浏览 3 评论 0原文

我不断地从另一个进程正在写入的内存映射文件中读取数据,并使用互斥锁来同步此操作。到目前为止,在我的几次测试中,这工作得很好,但是......如果我的应用程序在获取互斥体之后和释放它之前崩溃了怎么办?即使发生此类崩溃,是否有任何方法可以保证互斥体的释放?

另外,我将如何处理其他进程的崩溃,该进程可能尚未释放互斥体?每次调用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不知在何时 2025-01-10 06:07:02

当进程在拥有互斥锁的情况下结束时,操作系统将自动为您释放互斥锁。通过获取互斥锁来尝试这一点,然后引发新的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

随风而去 2025-01-10 06:07:01

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:

  • You took out the mutex to ensure that no one would mutate state while you were reading, or read state while you were mutating. Let's suppose the latter.
  • Another application wants to read the state, so it tries to take the mutex. It is forced to wait.
  • You mutated some state and then crashed.
  • The operating system released the mutex.
  • The other application now immediately acquires the mutex, and is now effectively reading state "while" another process is mutating it. The fact that the other process is now dead and gone means that the bogus state will now last forever, and the reading process will probably itself crash and die horribly. You have just defeated the safety system provided by the mutex.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文