mutex与semaphore的区别
网摘1:
Mutex 的发音是 /mjuteks/ ,其含义为互斥(体),这个词是Mutual Exclude的缩写。
Mutex在计算机中是互斥也就是排他持有的一种方式,和信号量-Semaphore有可以对比之处。有人做过如下类比:
* Mutex是一把钥匙,一个人拿了就可进入一个房间,出来的时候把钥匙交给队列的第一个。一般的用法是用于串行化对critical section代码的访问,保证这段代码不会被并行的运行。
* Semaphore是一件可以容纳N人的房间,如果人不满就可以进去,如果人满了,就要等待有人出来。对于N=1的情况,称为binary semaphore。一般的用法是,用于限制对于某一资源的同时访问。
对于Binary semaphore与Mutex,这两者之间就存在了很多相似之处:
在有的系统中Binary semaphore与Mutex是没有差异的。在有的系统上,主要的差异是mutex一定要由获得锁的进程来释放。而semaphore可以由其它进程释放(这时的semaphore实际就是个原子的变量,大家可以加或减),因此semaphore可以用于进程间同步。Semaphore的同步功能是所有系统都支持的,而Mutex能否由其他进程释放则未定,因此建议mutex只用于保护critical section。而semaphore则用于保护某变量,或者同步。
网摘2:
mutex与semaphore的区别
"互斥(mutext)和旗语(semaphore)之间有什么不同?"这样的问题简短而有力,但要回答却相当困难.即使有经验的实时操作系统(RTOS)用户在区别如何正确使用mutex和semaphore时也存在着困难.
但这一点很不幸而且很危险,因为无任这两种原生RTOS中的哪一种被错误使用,都会导致嵌入式系统出现意想不到的错误,特别是这些系统为有关生命安全的产品时.
有关mutex和semaphore的荒诞说法是它们是相似的,甚至是可以互换的.正确的事实是尽管mutex和semaphore在它们的执行上有相似之处,但是我们还是应该在使用它们时加以区别对待.
最
普遍(但也是不正确)的答案是:mutex和semphore非常相似,它们只有一个区别,那就是semaphores的计数可以超过1.
差不多所有的工程师都能正确的理解:mutex是一个二进制标志,可以通过它来确保执行流在代码关键区(critical section of code)互相排斥,从而对共享资源加一保护.但当他们被要求进一步回答如何使用"计算方法semaphore"的方式时,大部分工程师的回答就如同教科书书一般的刻板---semaphore用于保护多重同类资源.
通
过类比办法,我们很容易解释为什么"多重资源"场景是有缺陷的.如果你认为一个
mutex是由操作系统拥有的关键值的话,我们可以很容易地将个别的mutex比喻是城市咖啡店中一间浴室的钥匙.如果你想使用浴室,却找不到钥匙,你就
必须在一个队列中等候.同样地,mutex则协串行化多项任务,以取得全域资源的共享,并且为等待队列中的任务分配一个静候其循序渐进的位置.
但这种简单的资源保护协议并不使用于两间相同浴室的情况.如果把一个semaphore概括为一个mutex,使其能保护两个或更多相同的资源,那么在我们的比喻中,它就象是放着两把相同钥匙的蓝子,你可以用任何一把打开任何一扇浴室的门.
因此,semaphore本身并不能解决多个相同资源的问题.咖啡店中的客人可能只知道有一把钥匙,但并不知道哪间浴室可用.如果你试图以此方式使用semaphore,你将会发现需要更多的状态信息---它们通常是由不同的mutex所保护的共享资源.
正确使用semaphore是为了使信号从一项任务传至另一项任务.mutex意味着取得与释放,使用受保护共享资源的每一次任务都是以这样的顺序进行.相比之下,使用semaphore的任务通常不是发送信号,就是进入等待状态,不可能同时发生.
例如,任务1可能包含程序代码,当按下"电源"(power)按钮时,即可提出(如发送信号或增量)一个特别的semaphore; 任务2则依据相同的semaphore而用于唤醒显示器. 在这种情况下,其中一项任务是信号的生产者,另一项任务是信号的消费者.
用一个例子来做总结,首先展示如何使用mutex:
/* Task 1 */
mutexWait(mutex_mens_room);
// Safely use shared resource
mutexRelease(mutex_mens_room);
/* Task 2 */
mutexWait(mutex_mens_room);
// Safely use shared resource
mutexRelease(mutex_mens_room);
相应地,你总是采用下列方法使用semaphore:
/* Task 1 - Producer */
semPost(sem_power_btn); // Send the signal
/* Task 2 - Consumer */
semPend(sem_power_btn); // Wait for signal
重 要的是,semaphores可以被interrupt service routine(ISR)中断服务程序用来向task发送信号.发送一个semaphore是一个非阻塞的RTOS行为,并且ISR安全.因为这种技术排 除了在task级别的为了是中断不使能而引起的错误的可能性,从ISR中发出信号是一种使嵌入式软件更加可靠的设计方式.
如果这篇文章帮助到了你,你可以请作者喝一杯咖啡