自旋锁在单处理器单核架构中是否有用?

时间:2009-06-22 07:20:02

标签: operating-system locking

我对自旋锁的功能感到困惑。

自旋锁用于阻止进程重新调度。 但是,在只有一个核心的机器中,使用自旋锁是有用的 防止上下文切换?

4 个答案:

答案 0 :(得分:10)

简答:不。

根据http://uw714doc.sco.com/en/man/html.3synch/Intro.3synch.html

不得在单处理器系统上使用旋转锁。在最好的情况下,单处理器系统上的旋转锁将浪费资源,减慢锁的所有者;在最坏的情况下,它会使处理器死锁。

来自:http://blogs.microsoft.co.il/blogs/sasha/archive/2008/08/10/practical-concurrency-patterns-spinlock.aspx

在单处理器系统上,不需要自旋锁,因为仅在高IRQL上需要自旋锁同步。在高IRQL(上面的调度IRQL)上不能发生上下文切换,因此代替旋转获取线程可以简单地请求相关IRQL上的中断并返回;中断将被屏蔽,直到释放线程将IRQL降低到低于请求的IRQL。

对于单处理器系统,内核将忽略旋转计数值,并将其视为零 - 实质上使自旋锁成为无操作。

是的,旋转锁可能很有用,并可提高某些操作的效率。但是,通常您应该从互斥锁开始,如果分析显示它是瓶颈,您可能需要考虑自旋锁。

答案 1 :(得分:10)

您的观察结果很好:在单处理器系统上,没有必要等待资源,因为您也可以尽早切换线程。互斥体和信号量就是这样做的。

在多处理器系统上,另一个处理器上的线程可以在没有上下文切换的情况下释放锁。自旋锁是有用的,如果你不希望等待很长时间,因为它可能更快只是挂起,直到另一个线程解锁的东西。如果你在互斥上睡觉,你基本上可以确定一些重要的死时间,然后才能重新安排。

然而,在内核代码中,情况发生了变化:中断处理程序需要访问与内核其余部分共享的资源,但它们无法休眠。互斥锁会让内核进入休眠状态,所以你不能使用它们,但是自旋锁也没用,因为没有任何东西可以打断单处理器上的中断处理程序(好吧,也许是另一个中断,但这很可怕)。

在内核中,然后,在中断处理程序中的自旋锁编译为无操作。他们完全被遗忘了,就像你想象的那样。同时,为了防止竞争,内核其余部分中的自旋锁 在实际旋转某些内容之前禁用中断(因为可以调度内核任务)。如果它们与中断处理程序共享代码,则这些代码只需要自旋锁(而不是互斥锁)。

一般来说,你是对的:如果你有互斥锁自旋锁在单处理器上真的没有多大意义,因为互斥体会浪费更少的时间。

答案 2 :(得分:0)

是和否;取决于存在的操作系统,是否存在任何操作系统,以及您要实现的目标。

如果您拥有完整的多任务和多线程操作系统,那么您必须从它为您提供的集合中选择您的原语,否则您将面临效率低下和最糟糕的非工作同步的风险。每个操作系统都有自己的习语和首选机制,如果不遵循这些惯例,也会产生成本。

从完整内核(或者更深入到内核和设备驱动程序)中获得的内容越远,您会发现最好的习惯用语涉及低级同步原语。

即使是单核CPU也有中断处理程序,可以在任何一对指令之间执行(原则上),甚至在某些体系结构中的某些多周期指令中执行。这实际上是一种并发性,虽然比第二个核心弱,但是在前台线程和后台中的任何中断处理程序之间进行通信时需要同步原语。在单核中,前台线程之间的同步当然必须涉及上下文切换。

等待中断处理程序中设置的条件或硬件寄存器中设置的条件都是单核中的单个前台线程可能没有比旋转标志或寄存器更好的选择。

编辑:我试图澄清这个答案,以明确说明我所说的同步通常比任何特定操作系统的自旋锁实现更多。问题并不是针对什么操作系统(如果有的话)以及任何特定操作系统的标记。

答案 3 :(得分:0)

没有

有关更详细的答案,请参阅“How Do Locks Lock?”以及评论。