ChatGPT解决这个技术问题 Extra ChatGPT

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

监视器和信号量之间的主要区别是什么?

您可以将监视器视为二进制信号量。
请通过此albahari.com/threading/part2.aspx。我读过这篇文章,这是我读过的关于 Threading 的最好的一篇
我不认为你是对的,马克西姆。如果我没记错的话,信号量是“低级”结构,而监视器是一个成熟的对象。我记得我们在大学的操作系统课上简要介绍了监视器,但我不记得监视器与互斥体有何不同,除了它是面向对象的。我记得有一个问题可以使用监视器来解决,但是由于 C 语言的限制,我们不能在课堂上使用同样的方法。
Semaphore 和 Monitor 是非常不同的,但在功能上是相当的,因为您可以从另一个实现一个。您可以阅读 Hoare 的原始论文,该论文从 here 证明了它们的等价性

A
Anthony Williams

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

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

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

监视器就像公共厕所。一次只能有一个人进入。他们锁上门以防止其他人进来,做他们的事情,然后在他们离开时解锁。

信号量就像一个自行车出租点。他们有一定数量的自行车。如果您尝试租用一辆自行车并且他们有免费的,那么您可以使用它,否则您必须等待。当有人归还他们的自行车时,其他人就可以拿走它。如果你有一辆自行车,那么你可以把它交给其他人归还——自行车出租店不在乎谁归还它,只要他们把自行车拿回来。


+1 与公共浴室和自行车出租场所非常相似。我永远不会忘记现在两者之间的区别。
您的回答似乎与 stackoverflow.com/a/7336799/632951 相矛盾。那么谁是对的?
@Pacerier:我是:-)唯一的矛盾是高级/低级的事情。你可以从信号量构建一个监视器,它只是不是很整洁,正是因为监视器是一个比信号量更高级别的结构。信号量只是一个等待的计数器。我建议阅读“信号量小书”greenteapress.com/semaphores
@AnthonyWilliams:我可能怀疑您只能从信号量构建监视器的概念。另一种方式也是可能的,因此我们不能说监视器是比信号量更高级别的实体。
是的,您可以从监视器构建信号量。您始终可以从高级对象构建低级对象。高/低级别的东西是关于能力和操作范围的,而不是关于哪个可以用来构建另一个。
C
Community

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

监视器中条件变量的 wait() 和 signal() 操作类似于计数信号量的 P 和 V 操作。

等待语句可以阻塞一个进程的执行,而信号语句可以导致另一个进程被解除阻塞。但是,它们之间存在一些差异。当进程执行 P 操作时,它不一定会阻塞该进程,因为计数信号量可能大于零。相反,当等待语句被执行时,它总是阻塞进程。当任务对信号量执行 V 操作时,它要么解除阻塞等待在该信号量上的任务,要么在没有任务要解锁的情况下增加信号量计数器。另一方面,如果一个进程在没有其他进程可以解除阻塞的情况下执行信号语句,则对条件变量没有影响。信号量和监视器之间的另一个区别是,被 V 操作唤醒的用户可以立即恢复执行。相反,被信号操作唤醒的用户只有在监视器解锁时才会重新启动。此外,监视器解决方案比带有信号量的解决方案更结构化,因为数据和过程被封装在单个模块中,并且互斥是由实现自动提供的。

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


A
Andriy Tylychko

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

Monitor

Semaphore


但是,那么 Monitor 与 MuEx 有何不同呢?互斥锁的作用与信号量完全相同,但一次只允许一个线程访问关键区域。
是的,mnitor 和 mutex 有什么区别?
值得注意的是,信号量不控制对共享对象的访问,而是控制共享资源(将包含多个对象)。
@xbonez:如果我们看一下 java.util.ArrayList:它是一个对象还是多个对象的容器?嗯,两者同时存在。那么信号量是否适合控制对它的访问?我会说:不。
在接受的答案本身中提到,Monitor 正在实施互斥。请参阅“监视器对象的成员函数或方法将强制互斥,因此在给定时间只有一个线程可能对对象执行任何操作”
B
Billz

一行回复:

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

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


B
Barun

信号量:

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

例子:

一个只允许 50 名乘客获得任何剧院/公共汽车/火车/乐趣乘车/教室的 50 个座位(共享资源)的柜台。并且仅在有人腾出座位时才允许新乘客。指示任何浴室的空闲/占用状态的二进制标志。红绿灯是标志的好例子。他们通过调节道路上车辆的通行来控制流量(共享资源)

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

监视器 :

监视器通过与对对象感兴趣的线程进行通信来同步对对象的访问,要求它们获取访问权限或等待某些条件变为真。

例子:

父亲可以充当女儿的监护人,一次只允许她和一个男人约会。一位学校老师用指挥棒让一个孩子在课堂上发言。最后一个技术问题,帐户对象上的事务(通过线程)同步以保持完整性。


我认为道路十字路口的红绿灯也是一个二元标志:一条道路上的汽车或正交道路上的汽车都可以行驶(互斥)因此示例(3)与(2)相同。另外我认为这些例子是信号量的极端情况(平凡的情况),可以使用监视器来实现。 wikipedia中有更多典型例子。
e
e.doroskevic

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

相比之下,这些坏事都不会发生在显示器上。监视器直接对数据感到厌烦(它封装了数据),并且由于监视器操作是原子操作,因此不可能编写可以访问数据而不调用入口协议的代码。监控操作完成时会自动调用退出协议。

监视器有一个内置机制,用于在继续之前以条件变量的形式进行条件同步。如果条件不满足,则该过程必须等待,直到通知它条件的变化。当一个进程等待条件同步时,监视器实现会处理互斥问题,并允许另一个进程访问监视器。

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


除此之外,虽然信号量在一种语言中很常见,并且在教科书中作为一种具有有限原子运算符的变量出现,但信号量是监视器的一种特殊情况——因为它是一种具有有限原子运算符的变量,因为这就是监视器。上面关于信号量是“较低级别”的论点是似是而非的。
J
JacquesB

信号量是一种用于在线程之间进行协调的信号机制。示例:一个线程正在从 Internet 下载文件,而另一个线程正在分析文件。这是一个经典的生产者/消费者场景。下载文件时,生产者在信号量上调用 signal()。消费者在同一信号量上调用 wait() 以便在信号指示文件准备好之前被阻塞。如果在消费者调用等待时信号量已经发出信号,则调用不会阻塞。多个线程可以在一个信号量上等待,但每个信号只会解除对单个线程的阻塞。

计数信号量跟踪信号的数量。例如,如果生产者连续发出 3 次信号,则 wait() 可以被调用 3 次而不会阻塞。二进制信号量不算数,只有“等待”和“信号”状态。

互斥锁(互斥锁)是由单个线程拥有的锁。只有获得锁的线程才能重新释放它。其他试图获取锁的线程将被阻塞,直到当前所有者线程释放它。互斥锁本身并不锁定任何东西——它实际上只是一个标志。但是代码可以检查互斥锁的所有权,以确保一次只有一个线程可以访问某个对象或资源。

monitor 是一种更高级别的构造,它使用底层互斥锁来确保对某些对象的线程安全访问。不幸的是,根据上下文、平台和上下文,“监视器”这个词有几种不同的含义,但在 Java 中,监视器是一个与对象隐式关联的互斥锁,可以使用 {1 } 关键字。 synchronized 关键字可应用于类、方法或块,并确保一次只有一个线程可以执行代码。