内核同步-spin_lock系列

spin_lock_irq & spin_unlock_irq
在获得锁之前会禁止中断,释放锁时会使能中断,而不管在调用此函数前中断状态是怎么样的
spin_lock_irqsave & spin_unlock_irqrestore
类似spin_lock_irq,但会记住调用此函数之前的中断状态(是否使能),在释放锁时进行恢复
spin_lock_bh & spin_unlock_bh
会在请求锁的时候,禁止软中断(bh = bottom half,底半部)

三种环境:
进程上下文,软中断,硬中断
优先级依次增高,即后者能将前者打断,所以在低优先级环境中请求共享资源时,需要屏蔽掉高优先级运行,可以调用相应的spin_lock函数来达到这个目的。如果不这样做,就会发生死锁。
举例:A进程用spin_lock获得了某一资源,还未释放,此时中断来了,进入中断处理流程,若此时需要操作共享资源,则必须要用spin_lock请求锁,但这时假如进程A和中断处理流程在同一CPU上,则A没有机会再释放锁,导致中断处理流程中死锁。所以,进程A中必须要在获取锁之前屏蔽中断(只需屏蔽本地中断即可,因为假如中断处理流程在另外一个CPU上时,换一种说法,就是另外一个CPU产生了中断,其实和本CPU没有关系,进程A的操作不受影响,可以顺利释放锁)。

因为在不同的CPU上出现中断不会导致

进程A的状态被设为TASK_INTERRUPT,只是换出。当中断处理程序忙等被换出后,进程A还是有机会

获得CPU,执行并退出临界区。


*注:spin_lock_irq包含了local_irq_disable(禁止中断),preempt_disable(禁止内核抢占),以及spin_lock本身的操作。

假如只考虑多CPU同步的情况,spin_lock足够,因为不同CPU上运行的软/硬中断,对本地CPU并没有影响。