Mutexes
Mutex 对象可用于提供对资源的独占访问权限。 虽然 Mutex 类使用的系统资源比 Monitor 类更多,但它可以跨应用域边界进行封送,可用于多个等待操作以及同步不同进程中的线程。 有关托管同步机制的比较,请参阅同步基元概述。
有关代码示例,请参阅 Mutex 构造函数的参考文档。
使用 mutex
线程调用 mutex 的 WaitOne 方法来请求获取所有权。 在 mutex 可用或可选超时间隔结束前,该调用会一直处于阻止状态。 如果没有任何线程拥有它,则 mutex 将处于已发出信号状态。
线程通过调用 ReleaseMutex 方法来释放 mutex。 Mutex 具有线程关联;即 mutex 只能由拥有它的线程释放。 如果线程释放的 mutex 不是它拥有的,就会在线程中抛出 ApplicationException。
由于 Mutex 类派生自 WaitHandle,因此还可以调用 WaitHandle 的静态 WaitAll 或 WaitAny 方法,以请求获取 Mutex 的所有权以及其他等待句柄。
如果线程拥有 Mutex,此线程可以在重复的等待-请求调用中指定相同的 Mutex,而不会阻止执行;不过,它必须释放 Mutex,次数与释放所有权一样多。
放弃的 mutex
如果线程终止而未释放 Mutex,则认为已放弃 mutex。 这通常指示存在严重的编程错误,因为该 mutex 正在保护的资源可能会处于不一致状态。 在下一个获取 mutex 的线程中引发 AbandonedMutexException。
对于系统范围的 mutex,放弃的 mutex 可能指示应用程序已突然终止(例如,通过使用 Windows 任务管理器终止)。
本地 mutex 和系统 mutex
Mutex 有两种类型:本地 mutex 和命名系统 mutex。 如果使用接受名称的构造函数创建 Mutex 对象,此对象与同名的操作系统对象相关联。 命名系统 mutex 在整个操作系统中都可见,并且可用于同步进程活动。 可以创建多个表示同一命名系统 mutex 的 Mutex 对象,还能使用 OpenExisting 方法打开现有的命名系统 mutex。
本地 mutex 仅存在于进程中。 进程中引用本地 Mutex 对象的所有线程都可以使用本地 mutex。 每个 Mutex 对象都是单独的本地 mutex。
系统 mutex 的访问控制安全性
可借助 .NET Framework 进行查询和设置命名系统对象的 Windows 访问控制安全性。 建议从创建起立刻开始保护系统 mutex,因为系统对象是全局对象,因此可能被不是你自己的代码锁定。
若要了解 mutex 访问控制安全性,请参阅 MutexSecurity 和 MutexAccessRule 类、MutexRights 枚举、Mutex 类的 GetAccessControl、SetAccessControl 和 OpenExisting 方法,以及 Mutex(Boolean, String, Boolean, MutexSecurity) 构造函数。
注意
系统 mutex 的访问控制安全性仅适用于 .NET Framework,不适用于 .NET Core 或 .NET 5+。