Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 马桶钥匙示例中二进制信号量和互斥量之间的区别?_C_Multithreading_Posix_Mutex_Semaphore - Fatal编程技术网

C 马桶钥匙示例中二进制信号量和互斥量之间的区别?

C 马桶钥匙示例中二进制信号量和互斥量之间的区别?,c,multithreading,posix,mutex,semaphore,C,Multithreading,Posix,Mutex,Semaphore,我已经阅读了有关Stackoverflow这个主题的帖子,但无法理解其中的要点。也许我们可以把它们的区别局限于一个具体的例子 有一个带锁的厕所。 互斥体:一个线程接收密钥。如果任何其他线程需要进入厕所,它们将等待。现在的主人出来把钥匙交给警卫(OS内核),警卫将厕所的所有权交给另一个人 问题陈述:我看到所有人都同意共享资源必须由锁定它的线程中的同一个互斥锁解锁。但是对于二进制信号量,它也可以在任何其他线程中解锁。 现在请考虑信号量的执行。 第一个人到达厕所,执行wait语句,信号量结构的值从1变

我已经阅读了有关Stackoverflow这个主题的帖子,但无法理解其中的要点。也许我们可以把它们的区别局限于一个具体的例子

有一个带锁的厕所。 互斥体:一个线程接收密钥。如果任何其他线程需要进入厕所,它们将等待。现在的主人出来把钥匙交给警卫(OS内核),警卫将厕所的所有权交给另一个人

问题陈述:我看到所有人都同意共享资源必须由锁定它的线程中的同一个互斥锁解锁。但是对于二进制信号量,它也可以在任何其他线程中解锁。 现在请考虑信号量的执行。


第一个人到达厕所,执行wait语句,信号量结构的值从1变为0。现在,如果任何其他人(其他线程)来执行wait语句,它将阻塞,因为'value=0'。那么,为什么总是说任何其他线程都可以解锁马桶/关键部分,特别是当没有其他线程可以进入关键部分时

二进制信号量是一个常规信号量,只能有0(资源不可用)或1(资源可用),这与互斥锁(锁)没有区别

进程进入厕所后,信号量将减少,等待信号量的任何其他人都将被阻止进入关键区域。被阻塞的进程/线程/任何东西通常被保存在一种队列中;当进程离开马桶时,等待的第一个进程将被唤醒

我不确定您在哪里读到当信号量为0时线程可以解锁关键部分


(注意,可能存在实现差异)

二进制信号量和互斥量之间实际上没有任何区别

它们之间唯一的概念区别是互斥只能表示一个键,而信号量可以表示多个(编号的)键

就拿这个例子来说

共有5个厕所:

当你请求一个信号灯时,你会得到一把特定厕所的钥匙。 当你离开时,那个厕所和剩下的免费厕所排成一排

如果所有厕所都满了,那么任何人都不能进入


如果要使用互斥体解决此问题,则互斥体将保护密钥盒,并且您必须不断检查密钥是否可用,但信号量可以表示密钥集。

互斥体具有线程亲和力。只有获取互斥锁的线程才能释放它。信号量没有亲缘关系。这是互斥的一个很好的特性,它避免了事故,并且可以告诉你什么时候错了。互斥锁也可以是递归的,允许同一线程多次获取互斥锁。防止意外死锁的对策


有用的属性,您需要在编写并发代码时获得所有帮助。当然,信号灯也可以完成任务。

并非总是“第一个等待进程”才有机会撒尿。这完全取决于操作系统和/或为这些线程设置的选项。一个常见的情况是,最高优先级的线程被解锁进入。它们通常按优先级排序,所以我仍然要声明,如果线程X获得信号量单元,那么线程Y发送一个单元,线程Z可以到达并获得该单元。现在X和Z都认为他们有访问权。你有没有一个例子说明“任何其他线程都可以解锁”?因为正如你所说,这听起来确实不合逻辑。使用信号量并不能保证获取信号量单元的线程必须是唯一可以发回信号的线程。马丁,你能澄清一下另一个线程如何发回信号吗一个信号量,假设另一个前线程已经进入临界区,并将信号量的值设置为0?@这里的意思是确切的句子[信号量发布(或基本解锁)可以由不同的线程执行。但是,在互斥的情况下,它应该只由同一个线程解锁][链接]现在我明白了。有一点很微妙,线程不一定要调用wait命令,然后输入CS,然后发布信号量。任何线程都可以任意发布信号量(从而将信号量的值从0增加到1),而不必等待信号量。但是,这可能违反互斥性,因此一次可能有多个线程访问CS。因此,我的理解是,如果二进制信号量必须执行互斥函数,那么必须确保post命令之前始终有一个wait语句。这有很大的区别。任何线程都可以将一个单元发布到一个信号量,而不仅仅是先前碰巧获得该单元的线程。@MartinJames同样,任何线程都可以释放互斥锁,而不必是获得该锁的线程。所有这些细节都取决于实现它们的程序员。这是一种不好的做法,但在编程上并没有被禁止。是的,这是我不能真正理解的。对于二进制信号量,任何其他线程怎么可能在没有等待的情况下发布(信号)?@Umair锁或信号量只是内存中某个地方的一个简单数字,具有一些复杂的逻辑,可以对其进行原子更改,并使线程在想要阻止它时进入睡眠状态。向信号量发帖只不过是对一个数字进行原子递增,然后唤醒所有睡在上面的人。没有机制将锁或信号量“令牌”分配给特定的线程/任务。任何知道信号量/互斥量在内存中的位置的人都可以发布/解锁它。这是标准的pthread实现。有些较旧的(通常是自旋锁类型)实现没有这些现代约束/增强。在“互斥”一词的定义中,它没有说它必须具有这些属性