Windows平台上的.NET Mutex:我完成后会发生什么?

时间:2010-08-14 17:47:49

标签: c# .net windows mutex

我有一个简单的.NET程序,它会检查另一个实例是否已经启动:

    Mutex mutex = new Mutex(false,"MyMutexName");
    if (!mutex.WaitOne(1))
        return;

    try{
    //do stuff
    }
    catch{ //exceptions}
    finally
    {
        mutex.ReleaseMutex();
    }

我的问题是,如果你忘记在程序结束时释放它,那么互斥锁究竟会发生什么?在某些Windows控制面板组件中是否可见?它住在哪里?

3 个答案:

答案 0 :(得分:12)

它是一个命名的互斥锁,因此它是可见的,可以在其他进程中打开。 Windows在句柄上使用简单的引用计数。如果您没有自己Dispose()它,那么终结器将为您关闭句柄。如果你的程序很难轰炸并且永远不会执行终结器,那么Windows会在清理程序使用的资源时执行此操作。

这将自动减少引用计数。如果减少到零(没有其他进程打开句柄),则释放内核对象。

换句话说:无论事情多么糟糕,你都没有问题。实际的突变对象存在于内核内存池中。您可以使用SysInternals的WinObj工具查看它。

答案 1 :(得分:3)

互斥锁是操作系统级别的句柄。当你的过程发生时它们会被关闭(如果你没有尽快关闭它们,那就是。)

修改

好的,我明显误解了示例这个问题。如果您只是想检测是否存在另一个实例,那么您将创建一个命名的互斥锁(或类似的对象),只需检查其存在而不锁定它。

WaitOne的调用锁定了它,取得了所有权,而ReleaseMutex则取消了它(只要没有对WaitOne的额外调用)。如果在没有完全释放互斥锁的情况下结束线程,它会使对象处于错误状态,如Micah引用文中所述。

我提出的问题是关于在流程完成之前是否关闭句柄,这完全是另一回事。

附加

在SDK [API] [1]级别,当已经创建了相同名称的互斥锁时,您可以调用CreateMutex并期望失败。在.NET中(至少在4.0中),有一个[constructor] [2]填充createdNew bool。

[1]:http://msdn.microsoft.com/en-us/library/ms682411(VS.85).aspx CreateMutex

[2]:http://msdn.microsoft.com/en-us/library/bwe34f1k(v=VS.90).aspx Mutex

答案 2 :(得分:3)

来自MSDN

  

如果线程在拥有a时终止   mutex,据说是互斥体   弃。互斥体的状态是   设置为发信号,然后等待   线程获得所有权。如果没有人拥有   互斥体,互斥体的状态是   信号。从版本2.0开始   .NET Framework,一个   抛出AbandonedMutexException   获取的下一个线程   互斥。在版本2.0之前   .NET Framework,也不例外   抛出。

     

<强>注意

     

一个废弃的互斥体通常表示一个   代码中出现严重错误。当一个   线程退出而不释放   互斥,数据结构受到保护   由互斥体可能不在   一致的状态。下一个线程   请求互斥锁的所有权   处理此异常并继续,如果   数据结构的完整性   可以验证。

     

在系统范围的互斥锁的情况下,   废弃的互斥体可能表明一个   申请已被终止   突然(例如,通过使用   Windows任务管理器)。