我看到在一个只有1个CPU和非抢占式Linux内核(2.6.x)的系统上,spin_lock调用等同于一个空调用,并因此以这种方式实现。
我无法理解这一点:难道它不应该等同于对互斥锁进行休眠吗?即使在非抢占式内核中,例如中断处理程序仍可能被执行,或者我可能调用会使原始线程进入睡眠状态的函数。因此,一个空的spin_lock调用并不是“安全”的,就像如果它被实现为互斥锁一样。
有些地方我没有理解吗?
我看到在一个只有1个CPU和非抢占式Linux内核(2.6.x)的系统上,spin_lock调用等同于一个空调用,并因此以这种方式实现。
我无法理解这一点:难道它不应该等同于对互斥锁进行休眠吗?即使在非抢占式内核中,例如中断处理程序仍可能被执行,或者我可能调用会使原始线程进入睡眠状态的函数。因此,一个空的spin_lock调用并不是“安全”的,就像如果它被实现为互斥锁一样。
有些地方我没有理解吗?
如果在非可抢占内核上使用spin_lock()
来保护数据免受中断处理程序的干扰,你将会出现死锁(在单处理器机器上)。
如果中断处理程序在其他内核代码持有锁时运行,它将永远旋转,因为常规内核代码没有办法恢复并释放锁。
只有当锁持有者可以始终运行到完成时,才能使用自旋锁。
对于可能被中断处理程序所需的锁,解决方案是使用spin_lock_irqsave()
,它在持有自旋锁时禁用中断。在1个 CPU 上,没有中断处理程序可以运行,因此不会出现死锁。在SMP上,中断处理程序可能会在另一个 CPU 上开始自旋,但由于持有锁的 CPU 不能被中断,所以锁最终将被释放。
spin_lock_irqsave()
)。由于抢占,即使您从未预期过您的代码会在 SMP 系统上运行,您仍然需要实现适当的锁定。spin_lock_*
。如果不这样做,那么只要在您进入临界区时出现中断,系统就会死锁。根据定义,如果您使用的是非抢占式内核,则不会被抢占。如果您自己进行多任务处理,那不是内核的问题,而是您的问题。中断处理程序仍然可能被执行,但它们不会引起上下文切换。