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