什么时候应该使用互斥锁(mutex),什么时候应该使用信号量(semaphore)?

148

我们何时应该使用互斥锁(mutex),何时应该使用信号量(semaphore)?


2
可能是Java中的互斥锁和信号量是什么?主要区别是什么?的重复问题。 - Merlyn Morgan-Graham
13个回答

1

互斥锁是信号量的一种特殊情况。信号量允许多个线程进入临界区。创建信号量时,您需要定义有多少线程可以进入临界区。当然,您的代码必须能够处理对此临界区的多次访问。


0

我认为@Peer Stritzinger的答案是正确的。

我想在他的答案中加入以下引用来自David R Butenhof的书《Programming with POSIX Threads》。作者在第3章的第52页写道(重点是我的):

当调用线程已经锁定互斥量时,您无法锁定互斥量。尝试这样做的结果可能是错误返回(EDEADLK),也可能是自死锁,不幸的线程永远等待。您不能解锁未锁定或被另一个线程锁定的互斥量。锁定的互斥量归锁定它们的线程所有。如果需要“未拥有”的锁,请使用信号量。第6.6.6节讨论了信号量

有了这个想法,下面的代码片段说明了使用大小为1的信号量替代互斥锁的危险性。

sem = Semaphore(1)
counter = 0 // shared variable
----

Thread 1

for (i in 1..100):
  sem.lock()
  ++counter
  sem.unlock()
----

Thread 2

for (i in 1..100):
  sem.lock()
  ++counter
  sem.unlock()
----

Thread 3

sem.unlock()
thread.sleep(1.sec)
sem.lock()

如果只有线程1和2,计数器的最终值应该是200。但是,如果不小心将信号量引用泄漏给另一个线程并调用unlock,那么你就无法获得互斥。 使用互斥锁,这种行为在定义上是不可能的。


-1

二进制信号量和互斥锁是不同的。从操作系统的角度来看,二进制信号量和计数信号量的实现方式相同,而二进制信号量可以具有值0或1。

互斥锁 -> 只能用于代码关键部分的互斥目的。

信号量 -> 可以用于解决各种问题。二进制信号量可用于信令,并解决互斥问题。当初始化为0时,它解决了信令问题,当初始化为1时,它解决了互斥问题。

当资源数量更多且需要同步时,我们可以使用计数信号量。

在我的博客中,我详细讨论了这些主题。

https://designpatterns-oo-cplusplus.blogspot.com/2015/07/synchronization-primitives-mutex-and.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接