信号量
信号量仅仅是一个与数据结构相关得计数器。所有的内核线程在试图访问这个数据结构之前,都要检查这个信号量。可以把每个信号量看成一个对象。组成如下:
- 一个整数变量
- 一个等待进程得链表
- 两个原子方法:down() 和 up()
down()方法对信号量的值减1,如果这个新值小于0,该方法就把正在运行的进程加入到这个信号量链表,然后阻塞该进程(即调用调度程序)。up()方法对信号量的值加1,如果这个新的值大于或等于0,则激活这个信号量链表中的一个或多个进程。
每个要保护的数据结构都有它自己的信号量,其初始值为1。当内核控制路径希望访问到这个数据结构时,它在相应得信号量上执行down()方法。如果信号量得当前值不是负数,则允许访问这个数据结构。否则,把执行内核控制路径得进程加入到这个信号量得链表并阻塞该进程。当另一个进程在那个信号量上执行up()方法时,允许信号量链表上的应一个进程继续执行。
自旋锁(spin lock)
自旋锁与信号量非常相识,但是没有进程链表,当一个进程发现锁被另外一个进程锁着时,它就不停地“旋转”, 执行一个紧凑的循环指令直到锁打开。
自旋锁在单处理环境下是无效的。当内核控制路径试图访问一个上锁的数据结构时,它开始死循环。因此,内核控制路径可能因为正在修改受保护的数据结构而没有机会继续执行,也没有机会释放这个自旋锁。最终的结果可能是系统挂起。