Linux内核自旋锁:
Kernel中的自旋锁不能够在能够导致睡眠的环境中使用。举个例子,一个线程A获得了自旋锁L;这个时候,发生了中断,在对应的中断处理函数B中,也尝试获得自旋锁L,就会中断处理程序进行自旋。但是原先锁的持有者只有在中断处理程序结束后,采用机会释放自旋锁,从而导致死锁。
Linux内核为读/写自旋锁提供了操作API函数初始化、测试和设置自旋锁。API函数功能说明如下:
rwlock_init(lock) 初始化自旋锁值为0x01000000(未锁)。
read_lock(lock) 加读者锁,即将读者计数加1。
read_lock_irqsave(lock, flags) 加读者锁,即将读者计数加1。并且关中断,存储状态标识到flags中。
read_lock_irq(lock) 加读者锁,即将读者计数加1。并且关中断。
read_unlock(lock) 解读者锁,即将读者计数减1。
read_unlock_irqrestore(lock, flags) 解读者锁,即将读者计数减1。并且开中断,将状态标识从flags读到状态寄存器中。
read_unlock_irq(lock) 解读者锁,即将读者计数减1。并且开中断。
write_lock(lock) 加写者锁,即将写者锁置0。
write_lock_irqrestore(lock, flags) 加写者锁,即将写者锁置0。并且关中断,存储状态标识到flags中。
write_lock_irq(lock) 加写者锁,即将写者锁置0。并且关中断。
write_unlock(lock) 解写者锁,即将写者锁置1。
write_unlock_irqrestore(lock, flags) 解写者锁,即将写者锁置1。并且开中断,将状态标识从flags读到状态寄存器中。
write_unlock_irq(lock) 解写者锁,即将写者锁置1。并且开中断。
Linux用户态自旋锁:
Pthreads提供的与Spin Lock锁操作相关的API主要有:
pthread_spin_lock (pthread_spinlock_t *lock);
pthread_spin_trylock (pthread_spinlock_t *lock);
pthread_spin_unlock (pthread_spinlock_t *lock);
Windows内核自旋锁:
与linux内核自旋锁相同的是,windows下内核的自旋锁也与中断机制相关。s
KeInitializeSpinLock(lock)
KeAcquireSpinLock(lock, old_irql)
KeReleaseSpinLock(lock, new_irql)
自旋锁的实现:
1. 使用CAS操作实现, 即使用CPU指令 cmpxchg 来实现
2. 使用CPU指令 lock btr 或者 lock bts 来实现
一般而言cmpxchg要比lock bts指令快。cmpxchg只有在比较操作成功时才锁定系统总线,而lock bts则在整个指令执行过程中总会锁定系统总线。