我有几个线程获取互斥体然后终止。
互斥体存储在主存储库中,并在程序存在时正确释放。但是,当分配 Mutex 的线程存在时,互斥锁会自动释放,随后会获取 AbandonedMutexException(也根据文档)。
如何避免此异常,并在分配线程完成后继续使用互斥锁?.Net 中是否有另一个更合适的同步结构没有这个限制。
注意- 我正在寻找一种与 Mutex 具有相似语义的跨进程同步机制。
我有几个线程获取互斥体然后终止。
互斥体存储在主存储库中,并在程序存在时正确释放。但是,当分配 Mutex 的线程存在时,互斥锁会自动释放,随后会获取 AbandonedMutexException(也根据文档)。
如何避免此异常,并在分配线程完成后继续使用互斥锁?.Net 中是否有另一个更合适的同步结构没有这个限制。
注意- 我正在寻找一种与 Mutex 具有相似语义的跨进程同步机制。
对问题的回应
AFAIK 不存在这样的 Mutex 类。AbandonedMutexException 非常烦人,但它代表了一种没有自动解决方案的真实情况。
当你有跨进程,甚至是跨线程通信时,你必须处理这样一个事实,即任何一个参与实体都可能因各种原因意外并突然终止。互斥锁的存在是为了保护资源,如果一个线程在持有互斥锁时被放弃,操作系统就无法保证它以任何一致的方式留下数据。这非常重要,因为这意味着放弃线程可能会使其他线程依赖的某些不变量无效。
AbandonedMutexException 是一种主动说“坏事发生了,你现在处于不确定状态”的方式。对于操作系统,这里真的没有其他办法。
回复您的回答
EventWaitHandle 与 Mutex 不同,用于不同的目的。
互斥锁用于保护特定资源,就像锁定语句一样。当一个特定的线程获得一个互斥锁时,就说它拥有这个互斥锁。一次只能有一个所有者。因此,如果所有涉及的线程都同意仅在拥有 Mutex 所有权时才接触资源,则您可以跨 thread.s 安全地访问资源
EventWaitHandle 可以在一定程度上可视化为线程安全事件。它具有信号和非信号的概念,任何数量的线程都可以等待它达到信号状态。当它收到信号时,其中一个等待线程将被唤醒并开始处理。
您可以使用 EventWaitHandle 来实现一种线程安全形式。不是锁定所有权是访问资源的关键,而是从事件发出信号是访问资源的关键。然而,魔鬼再次出现在细节中。
看起来 EventWaitHandle 做了我想要的。它有一个带名字的构造函数,所以它非常适合跨进程同步,而且它没有这个问题。
在收到AbandonedMutexException
. 从文档:
下一个请求互斥锁所有权的线程可以处理此异常并继续,前提是可以验证数据结构的完整性。
当然,这假设您知道您(和您的线程)在崩溃时正在做什么,这基本上意味着获取线程也可以在退出之前释放互斥锁。
所以最终你自己的使用解决方案EvenWaitHandle
比互斥锁更好。