这是一个同事问我的问题。我并非专家,只是有基本的原理理解。首先排除上层的各种花里胡哨的锁的机制,基本的锁应该有如下的几种实现方式。
1.OS提供的内核对象方式提供的异步锁实现
这种方式下,锁的实现是内核对象,对外提供API,之所以说是异步是因为试图加锁的进程如果无法获取这个锁,内核的操作方式是将进程加入这个锁的等待队列之中。当该锁被释放之后,OS对于等待队列中的进程进行唤醒。
2.对于单CPU的IntMask方式的同步的锁实现
之所以说是同步是因为这种方式关中断,停止CPU的任务调度,这样我们可以保证互斥操作。
3.对于多CPU的处理器,多个CPU之间的Spin Lock
每个CPU只能关自己的中断,因此这个时候关中断无法保证全局互斥,需要找到一个全局的统一互斥点。我们依赖的是总线,各个CPU通过锁总线来进行竞争(据说Intel多核CPU提供了避免锁总线的机器指令)。锁总线之后,用一个全局变量来标识是否锁被占用。然后用deadloop的方式死等。
对于第一种情况,如果是统一调度,内核在多CPU的情况下也可以实现相应的内核锁对象。INTMASK是特权指令用户态不可使用,进程可以使用CPU提供的原子指令例如xchg自己实现锁。这也是一些用户态应用在多核环境中实现自定义lock的基础。
上述都是我没有深入code的原理性理解,可能不完全正确。