Monitor 和 Semaphore 之间的主要区别是什么?
答案 0 :(得分:494)
Monitor 是一个旨在从多个线程访问的对象。监视器对象的成员函数或方法将强制执行互斥,因此在给定时间只有一个线程可以对该对象执行任何操作。如果一个线程当前正在执行该对象的成员函数,则尝试调用该对象的成员函数的任何其他线程将必须等到第一个完成后才能执行。
信号量是较低级别的对象。您可能会使用信号量来实现监视器。信号量本质上只是一个计数器。当计数器为正时,如果线程试图获取信号量,则允许它,并且计数器递减。当一个线程完成后,它会释放信号量,并递增计数器。
如果线程试图获取信号量时计数器已经为零,那么它必须等到另一个线程释放信号量。如果一个线程释放信号量时多个线程正在等待,那么其中一个线程就会获得它。释放信号量的线程不必是获取信号量的线程。
显示器就像一个公共厕所。一次只能有一个人进入。他们锁门,以防止其他人进来,做他们的东西,然后在他们离开时解锁。
信号量就像一个自行车租赁场所。他们有一定数量的自行车。如果您尝试雇用一辆自行车并且他们有一辆免费,那么您可以接受它,否则您必须等待。当有人返回自行车时,其他人可以接受它。如果您有自行车,那么您可以将其交给其他人返回---自行车租赁处并不关心谁将其归还,只要他们将自行车放回去。
答案 1 :(得分:9)
以下说明实际上解释了监视器的wait()和signal()与信号量的P和V的不同之处。
监视器中条件变量的 wait()和信号()操作类似于 P 计算信号量时的 V 操作。
等待声明可以阻止进程的执行,而信号语句可以导致另一个进程被解除阻塞。但是,它们之间存在一些差异。当进程执行P操作时,它不一定阻止该进程,因为计数信号量可能大于零。相反,当执行wait语句时,它总是阻塞进程。当任务对信号量执行V操作时,如果没有要解锁的任务,它将取消阻塞等待该信号量的任务或增加信号量计数器。另一方面,如果进程在没有其他进程解除阻塞时执行信号语句,则对条件变量没有影响。信号量和监视器之间的另一个区别是,通过V操作唤醒的用户可以无延迟地恢复执行。相反,仅在监视器解锁时才重新启动通过信号操作唤醒的用户。此外,监视器解决方案比具有信号量的解决方案更结构化,因为数据和过程封装在单个模块中,并且实现自动提供互斥。
链接:here以供进一步阅读。希望它有所帮助。
答案 2 :(得分:5)
答案 3 :(得分:5)
一行答案:
监视器:一次只能控制一个线程在监视器中执行。 (需要获取锁来执行单个线程)
信号量:一个保护共享资源的锁。 (需要获取锁来访问资源)
答案 4 :(得分:2)
当信号量用于保护关键区域时,信号量与受保护数据之间没有直接关系。这是信号量可能分散在代码周围的部分原因,以及为什么很容易忘记调用等待或 通知 ,在哪种情况下,结果将分别违反互斥或永久锁定资源。
相比之下,监视器可能会发生这些不好的事情。监视器直接对数据感到厌倦(它封装了数据),并且由于监视操作是原子操作,因此编写无需调用入口协议即可访问数据的代码是不可能的。监视器操作完成后,将自动调用退出协议。
监视器在继续之前具有用于条件变量形式的条件同步的内置机制。如果不满足条件,则该过程必须等待直到通知条件的变化。当进程等待条件同步时,监视器实现会处理互斥问题,并允许其他进程访问监视器。
取自开放大学M362第3单元"互动过程"课程材料。
答案 5 :(得分:2)
信号量:
使用计数器或标志来控制对并发系统中某些共享资源的访问,意味着使用信号量。
示例:
标志仅显示资源的当前状态,没有关于资源上等待或运行对象的计数或任何其他信息。
监控:
监视器通过与对象感兴趣的线程通信,要求他们获取访问权限或等待某些条件成为真实来同步对Object的访问。
示例:
答案 6 :(得分:2)
信号量是一种用于在线程之间进行协调的信令机制。示例:一个线程正在从Internet下载文件,另一个线程正在分析文件。这是经典的生产者/消费者方案。下载文件时,生产者在信号量上调用signal()
。使用者在同一信号量上调用wait()
以便被阻塞,直到信号表明文件准备就绪为止。如果在使用者通话等待时已经发出了信号灯,则通话不会阻塞。多个线程可以等待一个信号量,但是每个信号只会解除阻塞单个线程。
计数信号量跟踪信号的数量。例如。如果生产者连续发出三次信号,则wait()
可以被调用三次而不会阻塞。二进制信号量不计算在内,而仅具有“等待”和“已信号传递”状态。
互斥锁(互斥锁)是由单个线程拥有的锁。只有获得了锁的线程才能再次实现该锁。尝试获取锁的其他线程将被阻塞,直到当前所有者线程释放它为止。互斥锁本身不会锁定任何内容,它实际上只是一个标志。但是代码可以检查互斥锁的所有权,以确保一次只有一个线程可以访问某些对象或资源。
监视器是一个更高级别的构造,它使用基础互斥锁来确保对某些对象的线程安全访问。不幸的是,根据上下文,平台和上下文,“监视程序”一词在几种不同的含义中使用,但是例如在Java中,监视程序是与对象隐式关联的互斥锁,并且可以用{{ 1}}关键字。 synchronized
关键字可以应用于类,方法或块,并确保一次只有一个线程可以执行代码。