互斥量和二进制信号量之间的实际区别

Posted

技术标签:

【中文标题】互斥量和二进制信号量之间的实际区别【英文标题】:Actual difference between Mutex and Binary semaphore 【发布时间】:2020-04-05 02:29:46 【问题描述】:

所以,上周,我正在研究 Mutex 和 Semaphores。我来找这个post 真的帮助我弄清楚信号量是什么。现在我明白了 理论上 的区别是什么,在 Binary Semaphore 和 Mutex 之间,我仍然想知道 如何 实际上使用它们。我目前正在使用 C#,但我找不到任何方法在这种语言中使用 Binary 信号量。

有人可以发布关于如何使用 Binary Semaphore vs Mutex 的任何(简单)代码示例吗?任何广泛使用的语言都可以完成这项工作。您甚至可以发布 Powershell/Bash 脚本。

【问题讨论】:

您的问题标题表明您想了解它们之间的差异,但您的问题正文要求提供代码示例。那你需要什么? 我想知道两者之间的实际(而不是理论上)差异。因此,显示一段代码将值一千字。不过,由同一操作系统/语言提供的关于互斥量和二进制信号量的文档也很重要…… 【参考方案1】:

一个非常粗略的近似是,如果您的执行线程需要在持有资源(即互斥体、sem)时阻塞,则不应使用互斥体。这种近似的问题在于,块在 UI 程序和中断处理程序中意味着不同的东西。阻塞是一个相对的概念。

互斥锁绑定到所有者;信号量不是。唯一可以释放互斥锁的代理是获得它的代理。信号量没有这个限制。由于这个限制,如果一个低优先级的代理阻塞了一个互斥锁上的一个高优先级的代理,监督者(内核,等等)可以提高所有者的优先级,直到它放弃它。这可以传递地应用于解决非循环优先级反转。信号量无法做到这一点,因为它们缺乏所有者的概念。

例如,线程 1 可以获取一个信号量,线程 2 可以等待它,线程 3 可以放弃它。这听起来可能很混乱,但它可能是更复杂系统的基础,其中线程 3 和 1 通过某种方式进行通信,因此线程 1 可以将资源的所有权直接交给线程 3。互斥锁无法做到这一点。

这就是说;我可以将 pthread_mutex_transfer(mutex, pthread) 破解到任何现有的实现中,对纯粹主义者和理论家嗤之以鼻。

【讨论】:

你不应该使用互斥体”为什么不呢? re:粗略近似。考虑与中断处理程序同步。如果您阻止持有互斥锁,例如等待来自不同设备的事件,您现在已经将中断设备绑定到信号设备。此外,中断设备可能会导致其他设备中断被延迟(一种不常见的中断结构),包括您被阻止的设备。即使是循环检测也可能会错过这一点,因为部分循环隐藏在某些外部总线设备中。 你可以用 UI 类型的代码构造类似的东西,其中一个对话框进入睡眠状态持有一个文件访问互斥锁,而程序的另一部分想要自动保存,但被文件访问阻止互斥体。它使程序比它们的设计框架更加缓慢和古怪。

以上是关于互斥量和二进制信号量之间的实际区别的主要内容,如果未能解决你的问题,请参考以下文章

Java 中的互斥量和信号量是啥?主要区别是啥?

锁、互斥量和信号量有啥区别?

信号量与互斥锁区别

使用互斥量和信号量的屏障实现

理解互斥量和信号量

FreeRTOS系列第20篇---FreeRTOS信号量API函数