我有几个线程获取互斥锁然后终止.
互斥锁存储在主存储库中,并在程序存在时正确释放.但是,当分配Mutex的线程存在时,互斥锁会自动释放,然后获取AbandonedMutexException(同样根据文档).
如何避免此异常,并在分配线程完成后继续使用Mutex?在.Net中是否存在另一个更合适的同步构造,它没有此限制.
注 - 我正在寻找一种与Mutex具有相似语义的跨进程同步机制.
回答这个问题
AFAIK没有这样的Mutex类.AbandonedMutexException非常烦人,但它代表了一种无法自动解决的真实情况.
当您进行跨进程,甚至是跨线程通信时,您必须处理这样一个事实:任何一个参与实体都可能出乎意料并因各种原因而突然终止.Mutex用于保护资源,如果线程在拥有互斥锁时被放弃,则操作系统无法保证它以任何一致的方式保留数据.这非常重要,因为这意味着放弃线程可能会使其他线程所依赖的某些不变量无效.
AbandonedMutexException是一种主动说"坏事发生而你现在处于不确定状态"的方式.这里没有其他操作系统的补偿.
回答你的回答
EventWaitHandle与Mutex的不同之处在于它具有不同的用途.
Mutex用于保护特定资源,就像锁定语句一样.当特定线程获得互斥锁时,它被称为拥有互斥锁.一次只能有一个所有者.因此,如果所涉及的所有线程同意仅在拥有Mutex的所有权时触摸资源,则可以安全地跨线程访问资源.
EventWaitHandle可以在某种程度上被视为线程安全事件.它具有信号和无信号的概念,任何数量的线程都可以等待它达到信号状态.当发出信号时,其中一个等待线程将被唤醒并开始处理.
您可以使用EventWaitHandle实现一种线程安全形式.锁定所有权不是访问资源的关键,而是从事件发出信号是访问资源的关键.然而,魔鬼再一次在细节中.
谁负责发出此事件的信号?使用互斥锁,每个线程基本上都在尖叫"我是我",操作系统选择一个线程来获胜.使用EventWaitHandle,您将负责决定下一个线程何时开始.
当有人通过taskmgr杀死进程时会发生什么?如果被杀死的进程当前正在响应EventWaitHandle上的事件,该怎么办?
2但是当接下来发出等待句柄信号的项目被取下时会发生什么?您必须考虑到这一点以避免死锁.