首页 > 信号量的原子操作是如何实现的?

信号量的原子操作是如何实现的?

操作系统有信号量(semaphore)的概念……检查数值、修改变量值以及可能发生的休眠操作均为单一的、不可分割的原子操作完成。保证一个一个信号量操作开始,则在操作完成或阻塞之前,其他进程均不允许访问该信号量。这种原子性对于解决同步问题和避免竞争条件是绝对比较的。

以上是摘自《现代操作系统》中的一段话,我的问题是:信号量的原子操作是如何实现的?


还记得小学上课的场景吗? 当老师问:“这个问题谁能回答?” 如果这时候所有知道答案的小盆友全都站起来回答,你一句我一句整个课堂会乱套了。 于是老师定下规则发言之前必须举手,由老师从举手的同学中挑一个来回答。当一个同学答完后,老师再挑下一位同学来回答。 这里的“举手”就是信号,通知给“老师”(操作系统),由“老师”(操作系统)统一进行调度。 所以整套机制的关键就是制定规则和执行调度的“老师”(操作系统)。 当你站在操作系统的角度,所有的线程都需要经过你来执行时,你会发现要实现信号量的实现并不难。


一般是采用CPU支持的特殊指令实现Compare-And-Swap。参见http://en.wikipedia.org/wiki/Compare-and-swap


信号量是建立在原子操作基础上的。

信号量实现的关键在于,如何原子地递增或者递减一个变量?

对于单 CPU 系统,在 x86 平台有对指定内存递增和递减的指令。然而,对多 CPU 系统这样仍然不够。为此,在多数 CPU 平台,使用特定的 lock 前缀,使得在指令执行过程中锁住内存总线,这样其它 CPU 由于得不到总线仲裁的许可,无法同时修改其值。

进程执行 P 操作的时候,首先原子地递减相应的计数,如果执行完之后小于零,则失败,扔到等待队列中。这个检查检查的是递减指令执行之后的标志,存放于 CPU 自己的寄存器中,不会与其它 CPU 共享,所以总是准确的。V 操作类似。

参考资料:《独辟蹊径品内核:Linux内核源代码导读》(李云华著),第 2.3.1、2.3.2 节。

【热门文章】
【热门文章】