将两个或多个互斥锁应用于一段代码

时间:2015-03-04 17:54:37

标签: c++ pthreads mutex deadlock

我正在研究来自http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html

的c ++ pthreads中的互斥锁和死锁

我理解他们,但我在某一点上堆积如山。我不明白下面代码的问题是什么。你能用简单明了的词解释一下吗?我引用了这个网站:

Mutex死锁:...将两个或多个互斥锁应用于一段代码时要小心。如果应用第一个pthread_mutex_lock并且第二个pthread_mutex_lock由于另一个线程应用互斥锁而失败,则第一个互斥锁最终可能会锁定所有其他线程访问数据,包括保存第二个互斥锁的线程。线程可能无限期地等待资源变得空闲,从而导致死锁。最好进行测试,如果发生故障,请在重试之前释放资源并停止。

01  ...
02  pthread_mutex_lock(&mutex_1);
03  while ( pthread_mutex_trylock(&mutex_2) )  /* Test if already locked   */
04  {
05     pthread_mutex_unlock(&mutex_1);  /* Free resource to avoid deadlock */
06         ...
07     /* stall here   */
08     ...
09     pthread_mutex_lock(&mutex_1);
10  }
11  count++;
12  pthread_mutex_unlock(&mutex_1);
13  pthread_mutex_unlock(&mutex_2);
14  ...

提前致谢。

2 个答案:

答案 0 :(得分:1)

基本上,如果您需要两个互斥锁来执行任务,mutex_1mutex_2,如果thread_A抓取mutex_1thread_B抓取mutex_2 ,他们陷入僵局,因为他们都在等待其他互斥体变得可用,但他们永远不会因为对方也在等待。

这就是为什么您通常会强制执行可以获取互斥锁的订单。例如,在尝试获取mutex_1之前,您必须获取mutex_2。这样,如果没有mutex_2,就不能拥有mutex_1,因此没有机会造成死锁。

     Thread_A                Thread_B
        |                       |
        |                       |
   lock(mutex_1)                |            // Thread_A got mutex_1
        |                       |
        |                  lock(mutex_2)     // Thread_B got mutex_2
        |                       |
        |                       |
  trylock(mutex_2)              |            // Thread_A wants mutex_2
        |                 trylock(mutex_1)   // Thread_B wants mutex_1
        |                       |

由于时间安排,这些线程现在陷入僵局。两者都在等待一个他们永远无法获得的互斥锁,因为另一个线程将无法解锁它所持有的互斥锁,直到它完成其工作。

在您的代码示例中,请注意他们所做的第一件事就是锁定mutex_1。然后他们旋转mutex_2直到可用。这是强制执行订单mutex_1然后mutex_2

答案 1 :(得分:1)

如果你锁定一个互斥锁,然后等待第二个,第一个仍然被锁定,所以没有其他人可以在你等待的时候得到它。这很糟糕,所以也许在你等待时解锁第一个互斥锁。代码显示了如何做到这一点。

如果另一个线程有你正在等待的互斥锁,并且需要你的互斥锁(它不应该,除非设计搞砸了),那么非常糟糕 - 两个线程都会等待永远,导致'#34;僵局" - 在你等待的时候,你肯定需要解锁第一个。

但在这种情况下,您应该正确修复它(如下一节所述) - 始终以明确定义的顺序锁定两个互斥锁。