【问题标题】:Releasing the mutex.释放互斥锁。
【发布时间】:2012-05-01 19:14:43
【问题描述】:

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

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

【问题讨论】:

    标签: .net multithreading mutex


    【解决方案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 也因做同样的事情而崩溃的事实无关。

    【讨论】:

    • 如果可以请执行我上一个问题中的代码。你会注意到在下一个线程中引发了异常。
    • 但是如果你可以检查代码的输出。线程释放不拥有它的互斥锁后,不会立即抛出应用程序异常。异常被延迟:(
    【解决方案2】:

    关于互斥锁的概念,您可以将其想象为一个抽屉,而拥有该互斥锁的线程则是持有该抽屉钥匙的人。只有持有抽屉钥匙的人才能解锁它,因此只有获得互斥锁的线程才能释放它。

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

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

    【讨论】:

      猜你喜欢
      • 2011-03-17
      • 2010-12-25
      • 2012-02-23
      • 1970-01-01
      • 2015-03-21
      • 2017-02-23
      • 2013-06-08
      • 2011-05-08
      • 2023-02-07
      相关资源
      最近更新 更多