代码之家  ›  专栏  ›  技术社区  ›  Carlos

Windows平台上的.NET互斥体:完成后它们会发生什么?

  •  10
  • Carlos  · 技术社区  · 16 年前

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

        Mutex mutex = new Mutex(false,"MyMutexName");
        if (!mutex.WaitOne(1))
            return;
    
        try{
        //do stuff
        }
        catch{ //exceptions}
        finally
        {
            mutex.ReleaseMutex();
        }
    

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

    3 回复  |  直到 9 年前
        1
  •  12
  •   Hans Passant    9 年前

    它是一个命名的互斥体,因此它是可见的,可以在其他进程中打开。Windows在句柄上使用简单的引用计数。如果您不自己显式地释放(),那么终结器将为您关闭句柄。如果你的程序爆炸很厉害,从不执行终结器,那么当它清理你的程序使用的资源时,Windows就会执行它。

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

    换言之:不管情况多么糟糕,你都不会有问题。实际的突变对象存在于内核内存池中。您可以通过系统内部的winobj工具看到它。

        2
  •  3
  •   Micah    16 年前

    从 MSDN

    如果线程在拥有时终止 互斥,互斥被称为 被遗弃的。互斥体的状态为 设置为“已发出信号”,下次等待 线程获得所有权。如果没有人拥有 互斥体,互斥体的状态为 发出信号。从版本2.0开始 .NET框架,一个 AbandonedMuteXException被抛出 下一个获取 互斥在版本2.0之前 .NET框架,没有异常 投掷。

    注意安全

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

    如果是系统范围的互斥,则 废弃的互斥可能表示 应用程序已终止 突然(例如,通过使用 Windows任务管理器)。

        3
  •  3
  •   Steven Sudit    16 年前

    互斥锁是操作系统级的句柄。当您的进程结束时,它们将被关闭(如果您不尽快关闭它们,也就是说)。

    编辑

    好吧,我明显误解了这个例子 和 这个问题。如果您只是试图检测另一个实例是否存在,那么您可以创建一个命名的互斥体(或类似的对象),并简单地检查它的存在,而不必锁定它。

    呼唤 WaitOne 锁定它,取得所有权,同时 ReleaseMutex 摆脱它(只要没有其他呼叫 侍者 )如果在不完全释放互斥体的情况下结束线程,则会使对象处于错误状态,如文本micah引号中所述。

    我认为你的问题是关于你是否关闭 手柄 在这个过程完成之前,这完全是另一回事。

    额外的

    在sdk[api][1]级别,可以调用 CreateMutex 当已经创建了相同名称的互斥体时,希望失败。在.NET中(至少在4.0中),有一个[构造函数][2]填充了 createdNew 布尔。

    〔1〕: http://msdn.microsoft.com/en-us/library/ms682411(VS.85).aspx 创建机器

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