Mutex的"安全"处理?

Mar*_*rio 8 c# mutex memory-mapped-files

我经常从另一个进程正在写入的内存映射文件中读取并使用互斥锁来同步此操作.到目前为止,在我的几个测试中,这个工作正常,但是...如果我的应用程序在获取互斥锁之后和释放之前崩溃了怎么办?有没有办法保证互斥锁的发布,即使发生了这样的崩溃?

另外,我如何处理其他进程的崩溃,这可能还没有释放互斥锁呢?每次调用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;
}
Run Code Online (Sandbox Code Playgroud)

_mmView是我之前实例化的MemoryMappedViewAccessor.整个方法GetState()作为游戏循环的一部分被调用每个帧,因此大约每隔几毫秒.

PS:此外,还有其他明显的问题,为什么这可能会失败,我还没有提到?

Eri*_*ert 11

Eugen的答案是正确的 - 操作系统将为您释放互斥锁.现在想一想这个事实的后果是什么:

  • 你取出了互斥锁,以确保在你阅读时没有人会改变状态,或者你在变异时读取状态.让我们假设后者.
  • 另一个应用程序想要读取状态,因此它尝试使用互斥锁.它被迫等待.
  • 你改变了一些状态然后崩溃了.
  • 操作系统发布了互斥锁.
  • 另一个应用程序现在立即获取互斥锁,现在有效地读取状态"而"另一个进程正在改变它.事实上,另一个过程已经死亡并且已经消失,这意味着虚假状态现在将永远存在,并且阅读过程本身可能会崩溃并且可怕地死亡.您刚刚击败了互斥锁提供的安全系统.

简而言之,你正在担心错误的事情.如果我的互斥锁永远不会被释放,你不应该担心会发生什么.然后发生的最糟糕的事情是每个人都在等待,这很难过,但最终用户将重启机器.你应该担心会发生什么,如果互斥量没有得到释放,因为我经历了突变中途坠毁.在那种情况下,流程现在可能会在整个地方崩溃,用户的数据将永久损坏.

首先不要陷入这种情况.解决问题的方法是在取出互斥锁写入时不要崩溃.如果你不编写崩溃的程序,那么你不必担心它,因为它不会发生.所以只是不要编写崩溃的程序.

  • @Mario:我不知道你认为什么是不现实的; 我向您保证,这些类型的数据损坏错误会频繁出现,如果您关心用户数据的状态,则必须予以保护.Re:如果用户崩溃该应用程序该怎么办?你问我当用户做破坏自己数据的东西时会发生什么?**他们的数据被破坏**,就是这样.不希望他们的数据被破坏的用户**不应该取消他们的应用程序**.有一个*原因*为什么这样做会出现一个对话框,上面写着"如果你这样做,你可能会损坏你的数据". (7认同)
  • 我和你一起仔细采取措施确保数据的完整性,但编写一个永远不会崩溃的无错误软件听起来像是一个非常难以实现的目标.总是会出现一个模糊的错误,你不认为任何事情都会发生,对吧?无论如何,在这种情况下,我不会改变状态 - 这是另一个过程的责任,因此超出了我的范围. (6认同)
  • "不要编写任何崩溃的程序",或者,正如禅师所说 - "避免错误".很棒的建议.啊哈. (3认同)