【问题标题】:.NET Mutex on windows platform: What happens to them after I'm done?Windows 平台上的 .NET Mutex:完成后它们会发生什么?
【发布时间】:2010-08-14 17:47:49
【问题描述】:

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

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

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

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

【问题讨论】:

  • 命名互斥体通常仅用于协调跨进程通信,这根本不是您的示例所显示的。
  • @Steven:为此使用互斥锁非常有用。比尝试检测以前的窗口或进程名称或其他东西要好得多。
  • 我更新了我的问题,因为您在代码中做了两个半相关的事情:1)使用命名互斥锁来检测应用程序的先前实例的存在 2)跨进程同步那个互斥体。

标签: c# .net windows mutex


【解决方案1】:

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

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

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

【讨论】:

  • 对,这就是我最初所说的手柄本身。这里的复杂之处在于,如果另一个进程获得了您命名的互斥锁的句柄,然后您在获得所有权后关闭了一个线程,则该互斥锁将被放弃。请参阅我的答案以了解更多详细信息。
  • 另外,Mutex.Dispose() 不会释放它。需要显式调用 ReleaseMutex(),否则新所有者会收到 AbandonedMutexException。
【解决方案2】:

来自MSDN

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

注意

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

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

【讨论】:

  • 澄清一下,使互斥锁成为“系统范围”的原因是多个进程拥有它的句柄。否则,当进程关闭时,它会带上互斥锁。
【解决方案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).aspxCreateMutex

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-07
    • 1970-01-01
    • 2012-03-22
    相关资源
    最近更新 更多