Mutex vs. Semaphore, what is the difference?

06 Aug 2012 by fleuria

  • 原文: http://koti.mbnet.fi/niclasw/MutexSemaphore.html
  • 作者: Niclas Winquist
  • 编译: fleuria

Mutex:

是一间厕所的钥匙。人要上厕所,必须先得到这枚钥匙。厕所上完了,这人会将厕所的钥匙交给(释放)排队的下一个人。

严肃:”Mutex一般用于序列化对一段不可重入代码的访问。Mutex在同一时刻只允许一个线程执行进入这段临界区,迫使其它试图进入临界区的线程进入等待,直到第一个线程离开为止。”

(Mutex实际上就是二元semaphore了。)

Ref: Symbian Developer Library

Semaphore:

是目前能用的n间厕所钥匙的数量。比方说,我们有四把不同的钥匙,对应着四间厕所。信号量——钥匙的数量——初始为4(4个厕所都能用),有人来上厕所了,这个数字就减1。如果厕所上满了,没了能用的钥匙,信号量的数就是0了。现在有一个人上完了厕所让出来一只钥匙(信号量增为1),就接着交给排队的下一个人。

严肃:”信号量控制着某共享资源同时可以被最多n个用户访问。线程在尝试访问资源时减少信号量,待用完了资源,再增加信号量来提示等待中的线程。”

Ref: Symbian Developer Library


绕舌且无关的译注:

Mutex与二元信号量的语义几乎一致,以至于在很长的一段时间内,linux内核中的睡眠锁就是信号量,在需要”长期”等待的情景中,二元信号量就扮演了Mutex的角色。然而它们的语义是有一点差异的。

Mutex相比信号量增加了所有权的概念,一只锁住的Mutex只能由给它上锁的线程解开,只有系铃人才能解铃。Mutex的功能也就因而限制在了构造临界区上。

二元信号量则可以由任一线程解开。这样多出来的一份语义,就是解决读者-写者问题的工具。

比如某进程读取磁盘并进入睡眠,等待中断读取盘块结束之后来唤醒它。这就是可以祭出二元信号量的一个情景,而Mutex是解决不了的。”信号量”这个词本身来自火车站的信号灯,其实暗含着一层”通知”的含义。

“同步”这个词也可以拆开看,一侧是等待数据的”事件”或者”通知”,一侧是保护数据的”临界区”。


无关译注2:

多元信号量的应用场景呢?

除了上文的n间厕所的例子,还有一个典型的例子便是管道的实现。管道有n块固定大小的循环缓冲区,就用n元信号量来保护它。写者写了一块,就减1,写满了就进入睡眠。读者读取了一块,就加1,这时可以唤醒写者。这也正是一个典型的读者-写者问题。