我最近从http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.34.1.tar.bz2下载了linux源代码。我在 linux-2.6.34.1\Documentation 文件夹中名为 spinlocks.txt 的文件中发现了以下段落。
”它确实意味着如果你有一些代码可以做到
cli();
.. critical section ..
sti();
还有另一个序列
spin_lock_irqsave(flags);
.. critical section ..
spin_unlock_irqrestore(flags);
那么它们并不相互排斥,并且临界区域可能会发生 同时在两个不同的CPU上。这本身很好,但是 关键区域最好对不同的事物具有关键性(即它们 不能互相踩踏)。 ”
如果某些代码使用 cli()/sti() 而同一代码的其他部分使用 spin_lock_irqsave(flags)/spin_unlock_irqrestore(flags),它们会如何影响?
最佳答案
这里的关键部分是“在两个不同的CPU上”。一些背景:
- 历史上,在单处理器 (UP) 系统上,唯一的并发源是硬件中断。在关键部分周围进行
cli/sti
就足以防止 IRQ 处理程序搞砸了。 - 然后是巨型锁设计,其中内核将有效地在单个CPU上运行,并且一次只有一个进程可以在内核中(这就是巨型锁的用途)。同样,禁用中断足以保护内核免受自身侵害。
- 在完整的 SMP 系统上,多个线程可以同时在内核中处于事件状态,并且中断可以传递到几乎任何 CPU,仅在单个处理器上禁用中断或仅获取单个锁已不再足够。两者都是必需的:禁用中断可防止同一 CPU 上的 IRQ 处理程序受到影响,持有锁可防止其他线程进入不同 CPU 上的相同临界区。这正是发明
spin_lock_irqsave()
和spin_unlock_irqrestore()
的原因。
关于linux-kernel - spinlock 和 cli 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3251754/