3

我有几个线程获取互斥体然后终止。

互斥体存储在主存储库中,并在程序存在时正确释放。但是,当分配 Mutex 的线程存在时,互斥锁会自动释放,随后会获取 AbandonedMutexException(也根据文档)。

如何避免此异常,并在分配线程完成后继续使用互斥锁?.Net 中是否有另一个更合适的同步结构没有这个限制。

注意- 我正在寻找一种与 Mutex 具有相似语义的跨进程同步机制。

4

3 回答 3

6

对问题的回应

AFAIK 不存在这样的 Mutex 类。AbandonedMutexException 非常烦人,但它代表了一种没有自动解决方案的真实情况。

当你有跨进程,甚至是跨线程通信时,你必须处理这样一个事实,即任何一个参与实体都可能因各种原因意外并突然终止。互斥锁的存在是为了保护资源,如果一个线程在持有互斥锁时被放弃,操作系统就无法保证它以任何一致的方式留下数据。这非常重要,因为这意味着放弃线程可能会使其他线程依赖的某些不变量无效。

AbandonedMutexException 是一种主动说“坏事发生了,你现在处于不确定状态”的方式。对于操作系统,这里真的没有其他办法。

回复您的回答

EventWaitHandle 与 Mutex 不同,用于不同的目的。

互斥锁用于保护特定资源,就像锁定语句一样。当一个特定的线程获得一个互斥锁时,就说它拥有这个互斥锁。一次只能有一个所有者。因此,如果所有涉及的线程都同意仅在拥有 Mutex 所有权时才接触资源,则您可以跨 thread.s 安全地访问资源

EventWaitHandle 可以在一定程度上可视化为线程安全事件。它具有信号和非信号的概念,任何数量的线程都可以等待它达到信号状态。当它收到信号时,其中一个等待线程将被唤醒并开始处理。

您可以使用 EventWaitHandle 来实现一种线程安全形式。不是锁定所有权是访问资源的关键,而是从事件发出信号是访问资源的关键。然而,魔鬼再次出现在细节中。

  1. 谁负责发出事件信号?使用互斥体,每个线程基本上都在尖叫“我我我”,操作系统选择一个线程来获胜。使用 EventWaitHandle,您将负责决定下一个线程何时开始。
  2. 当有人通过 taskmgr 杀死进程时会发生什么?如果被杀死的进程有一个线程当前正在响应 EventWaitHandle 上的事件怎么办?
  3. 2 但是当下一个发出信号等待句柄的项目被取下时会发生什么?您必须考虑到这一点以避免死锁。

于 2009-03-17T13:47:28.017 回答
1

看起来 EventWaitHandle 做了我想要的。它有一个带名字的构造函数,所以它非常适合跨进程同步,而且它没有这个问题。

于 2009-03-17T13:27:26.223 回答
0

在收到AbandonedMutexException. 从文档

下一个请求互斥锁所有权的线程可以处理此异常并继续,前提是可以验证数据结构的完整性。

当然,这假设您知道您(和您的线程)在崩溃时正在做什么,这基本上意味着获取线程也可以在退出之前释放互斥锁。

所以最终你自己的使用解决方案EvenWaitHandle比互斥锁更好。

于 2012-07-08T21:42:48.130 回答