";“安全”;处理Mutex

本文关键字:处理 Mutex quot 安全 | 更新日期: 2023-09-27 18:22:40

我不断地从另一个进程正在写入的内存映射文件中读取,并使用互斥来同步此操作。到目前为止,在我的几次测试中,这一切都很好,但。。。如果我的应用程序在获取互斥对象之后并在释放它之前崩溃,该怎么办?有没有任何方法可以保证互斥锁的释放,即使是在这种崩溃的情况下?

此外,我将如何处理另一个进程的崩溃,该进程可能还没有释放互斥对象?每次调用互斥对象时,是否需要处理废弃互斥异常。WaitOne()?

现在我正在做类似的事情:

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()作为游戏循环的一部分在每一帧中被调用,大约每隔几毫秒调用一次。

附言:还有其他明显的问题吗?为什么这会失败,我还没有提到?

";“安全”;处理Mutex

Eugen的答案是正确的——操作系统将为您释放互斥对象。现在仔细想想这个事实的后果是什么:

  • 您取出互斥锁,以确保在您读取时没有人会改变状态,或者在您更改时不会改变状态。让我们假设后者
  • 另一个应用程序想要读取状态,所以它试图获取互斥。它被迫等待
  • 你改变了一些状态,然后崩溃了
  • 操作系统释放了互斥锁
  • 另一个应用程序现在立即获取互斥对象,并且现在有效地读取状态"而"另一个进程正在对其进行更改。另一个进程现在已经死了,这意味着伪状态将永远,读取进程本身可能会崩溃并可怕地死去您刚刚击败了互斥锁提供的安全系统

简而言之,你担心的是完全错误的事情。您不应该担心如果我的互斥对象从未被释放会发生什么当时发生的最糟糕的事情是每个人都在等待,这很可悲,但最终用户会重新启动机器。您应该担心如果互斥确实被释放会发生什么,因为我在突变的中途崩溃了。在这种情况下,进程现在可能会到处崩溃,用户的数据将被永久损坏

一开始就不要陷入那种境地。问题的解决方案是,当您取出一个用于写入的互斥对象时,不要崩溃。如果你不编写崩溃的程序,那么你就不必担心它,因为它不会发生。所以只是不要编写会崩溃的程序

当进程在拥有互斥对象时结束时,操作系统将自动为您释放互斥对象。通过获取互斥,然后raise new WhateverException()来尝试这一点——另一个进程将继续

对于所有同步基元AFAIK 也是如此