我看过Stackoverflow上关于这个话题的帖子,但不明白要点。也许我们可以将它们的差异限制在一个具体的例子中。
有一个带锁的马桶。互斥:一个线程拿着钥匙进去。如果任何其他线程需要进入马桶,它们会等待。当前的所有者出来并将钥匙交给警卫(操作系统内核),后者将马桶的所有者船交给另一个人。
问题陈述:我看到所有人都同意共享资源必须由锁定它的线程中的相同互斥锁解锁。但是对于二进制信号量,它也可以在任何其他线程中解锁。现在请考虑信号量的实现。
第一个人到达厕所,执行等待语句,信号量结构的值从1到0。现在如果任何其他人(其他线程)来执行等待语句,它会阻塞,因为“值=0”。那么为什么总是说任何其他线程都可以解锁厕所/临界区,特别是当没有其他线程可以进入临界区时?
互斥体具有线程亲和性。只有获得互斥锁的线程才能释放它。信号量没有相关性。这是互斥锁的一个很好的特性,它可以避免意外,并可以告诉您何时出错。互斥锁也可以是递归的,允许同一线程多次获取它。防止意外死锁的对策。
有用的属性,在编写并发代码时,你需要你能得到的所有帮助。当然,信号量也可以完成这项工作。
二进制信号量是一个常规信号量,其值只能为0(资源不可用)或1(资源可用),这与互斥锁(锁)之间没有区别。
进程进入厕所后,信号量递减,任何等待信号量的其他人都被阻止进入临界区。被阻塞的进程/线程/任何东西通常被保持在一种队列中;当进程离开厕所时,第一个等待的进程将被唤醒。
我不确定您在哪里读到线程可以在信号量为0时解锁临界区。
(注意,可能存在实施差异)
二进制信号灯和互斥锁之间实际上没有任何区别。
它们之间唯一的概念区别是互斥体只能代表一个键,而信号量可以代表多个键。
以这个例子为例。
有5个厕所:
当你请求一个信号量时,你会得到一个特定厕所的钥匙。当你出去的时候,那个厕所和剩下的免费厕所排在一起。
如果所有的厕所都满了,就没人能进去了。
如果要使用互斥锁解决此问题,则互斥锁将保护键盒,并且您必须持续检查密钥是否可用,但信号量可以表示密钥集。