Posted on 2012-11-09 16:34
鑫龙 阅读(335)
评论(0) 编辑 收藏 引用 所属分类:
linux内核
自旋锁可分为用在单核处理器上和用在多核处理器上。单核处理器:
用在单核处理器上,又可分为两种:
1.系统不支持内核抢占
此时自旋锁什么也不做,确实也不需要做什么,因为单核处理器只有一个线程在执行,又不支持内核抢占,因此资源不可能会被其他的线程访问到。
2.系统支持内核抢占
这种情况下,自旋锁加锁仅仅是禁止了内核抢占,解锁则是启用了内核抢占。
在上述两种情况下,在获取自旋锁后可能会发生中断,若中断处理程序去访问自旋锁所保护的资源,则会发生死锁。因此,linux内核又提供了spin_lock_irq()和spin_lock_irqsave(),这两个函数会在获取自旋锁的同时(同时禁止内核抢占),禁止本地外部可屏蔽中断,从而保证自旋锁的原子操作。
多核处理器:
多核处理器意味着有多个线程可以同时在不同的处理器上并行执行。举个例子:
四核处理器,若A处理器上的线程1获取了锁,B、C两个处理器恰好这个时候也要访问这个锁保护的资源,因此他俩CPU就一直自旋忙等待。D并不需要这个资源,因此它可以正常处理其他事情。
自旋锁的几个特点:
1.被自旋锁保护的临界区代码执行时不能睡眠。单核处理器下,获取到锁的线程睡眠,若恰好此时CPU调度的另一个执行线程也需要获取这个锁,则会造成死锁;多核处理器下,若想获取锁的线程在同一个处理器下,同样会造成死锁,若位于另外的处理器,则会长时间占用CPU等待睡眠的线程释放锁,从而浪费CPU资源。
2.被自旋锁保护的临界区代码执行时不能被其他中断打断。原因同上类似。
3.被自旋锁保护的临界区代码在执行时,内核不能被抢占,亦同上类似。