释放互斥锁。

时间:2012-05-01 19:14:44

标签: .net multithreading mutex

“Mutex类强制执行线程标识,因此互斥锁只能由获取它的线程释放。相比之下,Semaphore类不强制执行线程标识。”

这是MSDN描述所说的..但根据我的问题Application exception is thrown,即使我没有获得它,我也尝试释放互斥锁。它在下一个线程执行时向我显示了一个异常。这是否意味着没有访问互斥锁的线程释放它?有人可以帮助我理解这个概念,如果我做错了,请指导我。

2 个答案:

答案 0 :(得分:1)

就像文档所说,引发了ApplicationException,因为没有拥有互斥锁的线程试图释放它。这并不意味着互斥锁被释放,只是试图释放它的线程没有拥有它。

var mutex = new Mutex();
mutex.WaitOne();
var thread = new Thread(() =>
    {
       try
       {
          mutex.ReleaseMutex(); //This will throw ApplicationException
       }
       catch (ApplicationException ex)
       {
           Console.WriteLine("Failed to release mutex");
       }
    });

thread.Start();
thread.Join();

mutex.ReleaseMutex(); //No exception will be thrown here

在此示例中,初始线程创建互斥锁并获取它。第二个线程将被旋转,尝试释放它并失败。失败后,拥有的线程将释放它。

<强>更新

在上一个问题中,重要的是要注意您正在运行具有多个线程的代码,并且每个线程中都存在相同的竞争条件。当一个线程保持在线程上时,多个线程可能无法获取互斥锁,因此多个线程同样无法释放它。以下面的执行路径为例。

  • 线程1获取互斥锁。
  • 线程2无法获取互斥锁,因为线程1拥有它。
  • 线程3无法获取互斥锁,因为线程1拥有它。
  • 线程3尝试释放互斥锁,抛出一个ApplicationException,因为它不拥有它。
  • 线程1释放互斥锁。
  • 线程2尝试释放互斥锁,抛出一个ApplicationException,因为它不拥有它。

线程3在未能释放互斥锁时爆炸的事实与线程2 通过执行相同操作而爆炸的事实无关。

答案 1 :(得分:0)

关于mutex的概念,您可以将其视为抽屉,并将拥有互斥锁的线程视为持有该抽屉键的人。只有持有抽屉钥匙的人才能将其解锁,因此只有获得互斥锁的线程才能释放它。

当你尝试从不拥有互斥锁的线程中释放互斥锁时,就像有人试图用假密钥打开别人的抽屉一样,所以抛出一个异常来抓住窃贼!

这就是互斥锁所做的一切,它可以防止多个线程执行“受保护的代码”(在抽屉内)。它的名字来自“互斥”,这意味着一次一个线程。