信号量与监视器-有什么区别?


233

MonitorSemaphore之间的主要区别是什么?


8
您可以将Monitor视为二进制信号量。
Maxim Egorushkin 2011年


1
请浏览此albahari.com/threading/part2.aspx。我读了这篇文章,最好的一个我穿线读过
山塔努古普塔

5
我不认为你是对的,马克西姆。如果我没有记错的话,信号量是“低级”结构,而Monitor是成熟的对象。我记得我们在大学的操作系统课程中曾经简要介绍过Monitors,但是我不记得Monitor是与Mutex区别的,除了它是面向对象的。我记得使用监视器可以解决一个问题,但是由于C语言的限制,我们不能在课堂上使用相同的方法。
user919860 2011年

1
信号量和Monitor的区别非常大,但在功能上相当,因为您可以彼此实现。您可以从这里
Thanh DK 2012年

Answers:


529

监视器是设计成从多个线程访问的对象。监视对象的成员函数或方法将强制相互排斥,因此在给定时间只有一个线程可以对该对象执行任何操作。如果一个线程当前正在执行该对象的成员函数,则任何其他试图调用该对象的成员函数的线程都必须等待,直到第一个线程完成。

信号量是一种较低级的对象。您可能会使用信号量来实现监视器。信号量实质上只是一个计数器。当计数器为正数时,如果线程尝试获取信号量,则允许该信号量,并且计数器递减。线程完成后,它将释放信号量,并增加计数器。

如果在线程尝试获取信号量时计数器已经为零,则它必须等到另一个线程释放该信号量。如果一个线程释放一个信号量时有多个线程正在等待,则其中一个会得到它。释放信号量的线程不必与获取信号量的线程相同。

监视器就像公共厕所。一次只能输入一个人。他们锁上门以防止其他任何人进来,处理自己的东西,然后在离开时将其解锁。

信号灯就像自行车出租处。他们有一定数量的自行车。如果您尝试租用一辆自行车,而他们有一辆免费的自行车,则可以搭乘,否则必须等待。当有人将自行车归还时,其他人可以骑它。如果您有一辆自行车,则可以将其交给其他人归还---自行车出租处并不关心谁归还它,只要他们把自行车归还。


162
+1与公共浴室和自行车出租场所的相似之处。我永远不会忘记现在两者之间的区别。
Drupad Panchal 2011年

4
您的答案似乎与stackoverflow.com/a/7336799/632951 ..那么谁是对的?
Pacerier,2011年

6
@Pacerier:我是:-)唯一的矛盾是高层/低层的事情。您可以从信号量构建一个监视器,这不是很整洁,这恰好是因为监视器是一个比信号量更高的结构。信号量只是等待的计数器。我建议阅读“信号量小书” greenteapress.com/semaphores
Anthony Williams

3
@AnthonyWilliams:我可能会怀疑只能从信号量构建监视器的观点。另一种方法也是可行的,因此,我们不能大胆地说监视器是比信号量更高的实体。
卡维什·德维维第

5
是的,您可以从监视器构建信号灯。您始终可以从高级对象构建低级对象。高/低级内容与功能和操作范围有关,而与可用于构建其他内容无关。
安东尼·威廉姆斯

11

以下解释实际上说明了监视器的wait()和signal()与信号量的P和V有何不同。

监视器中对条件变量进行的wait()signal()操作类似于对信号量进行计数的PV操作。

等待语句可以阻止进程的执行,而信号语句可以导致另一个进程被取消阻止。但是,有一些差异它们之间。当进程执行P操作时,它不一定会阻塞该进程,因为计数信号量可能大于零。相反,当执行wait语句时,它总是阻塞进程。当任务在信号量上执行V操作时,它会取消阻止等待该信号量的任务,或者如果没有要解锁的任务,则增加信号量计数器。另一方面,如果在没有其他要取消阻塞的进程的情况下一个进程执行了信号声明,则对条件变量没有影响。信号量和监视器之间的另一个区别是,被V操作唤醒的用户可以立即恢复执行。相反,仅当监视器解锁时,通过信号操作唤醒的用户才会重新启动。此外,

链接:此处供进一步阅读。希望能帮助到你。


6

一线回答:

监控器:一次 只能控制一个线程在监控器中执行。(需要获取锁才能执行单线程)

信号量: 保护共享资源的锁。(需要获取访问资源的锁)


5

信号量允许多个线程(最多设置数量)访问共享对象。监视器允许互斥访问共享对象。

监控

信号


10
但是,监视器与MutEx有何不同?互斥锁与信号灯具有相同的作用,但一次只允许一个线程访问关键区域。
user919860 2011年

2
是的,助记符和互斥锁有什么区别?
Pacerier,2011年

2
值得注意的是,信号量不控制对共享对象的访问,而是控制共享资源(将包含多个对象)的访问。
xbonez 2012年

@xbonez:如果我们看java.util.ArrayList:是一个对象还是多个对象的容器?好吧,这是同时存在的。那么信号量是否适合控制对它的访问?我会说:不。
dma_k '16

在接受的答案本身中,提到了Monitor正在实施互斥。请参阅“监视对象的成员函数或方法将强制相互排斥,因此在给定时间只有一个线程可以对该对象执行任何操作”
achoora

2

当使用信号量保护关键区域时,信号量与受保护的数据之间没有直接关系。这就是为什么信号可能散布在代码周围以及为什么容易忘记调用waitnotify的部分原因,在这种情况下,结果将分别是违反互斥或永久锁定资源。

相反,监视器可能会发生这些不良情况。监视器直接对数据感到厌倦(它封装了数据),并且由于监视器操作是原子操作,因此如果不调用入口协议就无法编写可以访问数据的代码。监视操作完成后,将自动调用退出协议。

监视器具有内置的机制,可以在进行操作之前以条件变量的形式进行条件同步。如果不满足条件,则该过程必须等待,直到被通知条件发生变化。当进程正在等待条件同步时,监视器实现将解决互斥问题,并允许另一个进程访问监视器。

摘自公开大学M362第3单元“交互过程”课程材料。


除此之外,尽管信号灯在一种语言中非常普遍,并且在教科书中显示为一种具有有限原子运算符的变量,但是信号灯是监视器的一种特殊情况 - 因为它是一种具有有限原子运算符的变量,因为那是监视器。上面关于信号量是“较低级别”的争论是似是而非的。
philipxy

2

信号量:

使用计数器或标志控制并发系统中某些共享资源的访问,意味着使用Semaphore

例:

  1. 一个仅允许50位乘客获得任何剧院/公共汽车/火车/趣味游乐设施/教室的50个座位(共享资源)的柜台。并且仅在有人腾出座位时允许新乘客乘坐。
  2. 一个二进制标志,指示任何洗手间的空闲/占用状态。
  3. 红绿灯是标志的一个很好的例子。它们通过调节车辆在道路上的通过来控制流量(共享资源)

标志仅显示资源的当前状态,不显示有关资源上正在等待或正在运行的对象的计数或任何其他信息。

监控器:

一个监视器与感兴趣的是对象的线程沟通,要求他们获取访问或等待一些条件,以成为真正的同步访问对象。

例:

  1. 父亲可以充当女儿的监护人,一次只能与一个人约会。
  2. 一位学校教师使用警棍,只允许一个孩子在课堂上讲话。
  3. 最后是技术性的,同步Account对象上的事务(通过线程)以维护完整性。

我认为十字路口的交通信号灯也是一个二元旗:在一条道路上或在正交道路上的汽车都可以行驶(相互排斥),因此示例(3)与(2)相同。我也认为这些示例是信号量的极端情况(琐碎的情况),可以使用监视器来实现。维基百科中有更多典型示例。
dma_k '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.