什么时候应该使用螺旋锁而不是互斥锁?

时间:2011-05-03 13:01:27

标签: synchronization mutex spinlock

我认为两者都在做同样的工作,你如何决定使用哪一个进行同步?

7 个答案:

答案 0 :(得分:659)

答案 1 :(得分:7)

继续Mecki的建议,这篇文章pthread mutex vs pthread spinlock在Alexander Sandler的博客上,Alex在Linux上展示了spinlock&可以实现mutexes以使用#ifdef测试行为。

但是,请务必根据您的观察结果进行最后的调用,理解为给出的示例是一个孤立的案例,您的项目要求,环境可能完全不同。

答案 2 :(得分:6)

另请注意,在某些环境和条件下(例如在调度级别的Windows上运行> = DISPATCH LEVEL),您不能使用互斥锁,而是使用自旋锁。 在unix上 - 同样的事情。

以下是竞争对手stackexchange unix网站上的同等问题: https://unix.stackexchange.com/questions/5107/why-are-spin-locks-good-choices-in-linux-kernel-design-instead-of-something-more

有关在Windows系统上调度的信息: http://download.microsoft.com/download/e/b/a/eba1050f-a31d-436b-9281-92cdfeae4b45/IRQL_thread.doc

答案 3 :(得分:6)

Mecki的回答非常好。但是,在单个处理器上,当任务等待中断服务程序给出的锁定时,使用自旋锁可能有意义。中断将控制权转移到ISR,这将使资源准备好供等待任务使用。它会在将控制权交还给被中断的任务之前释放锁定而结束。旋转任务会找到螺旋锁并继续。

答案 4 :(得分:3)

Spinlock和Mutex同步机制在今天非常普遍。

让我们首先考虑一下Spinlock。

基本上它是一个繁忙的等待操作,这意味着我们必须等待指定的锁被释放才能继续下一个操作。从概念上讲很简单,虽然实现它并不是这样的。例如:如果锁没有被释放,那么线程被换出并进入睡眠状态,我们应该处理它吗?当两个线程同时请求访问时如何处理同步锁?

通常,最直观的想法是通过变量处理同步以保护关键部分。 Mutex的概念类似,但它们仍然不同。关注:CPU利用率。 Spinlock消耗CPU时间等待做动作,因此,我们可以总结两者之间的差异:

在同构多核环境中,如果在临界区上花费的时间比使用Spinlock小,因为我们可以减少上下文切换时间。 (单核比较并不重要,因为有些系统在交换机中间实现了Spinlock)

在Windows中,使用Spinlock会将线程升级到DISPATCH_LEVEL,在某些情况下可能不允许,所以这次我们不得不使用Mutex(APC_LEVEL)。

答案 5 :(得分:0)

使用自旋锁的规则很简单:只有且仅在实时持有锁的时间有限且足够小时,才使用自旋锁。

请注意,通常用户实现的自旋锁不满足此要求,因为它们不禁用中断。除非禁用了抢占功能,否则在按住自旋锁的同时进行抢占行为将违反限制的时间要求。

判断调用足够小,取决于上下文。

例外:即使没有时间限制,某些内核编程也必须使用自旋锁。特别是,如果CPU没有工作要做,它只能旋转直到出现更多工作为止。

特殊危险:在低级编程中,当存在多个中断优先级时(通常至少有一个不可屏蔽的中断)要格外小心。即使禁用了线程优先级的中断(例如,优先级硬件服务,通常与虚拟内存管理相关),在这种更高优先级的抢占中也可以运行。如果维持严格的优先级分隔,则必须放宽有界实时的条件,并以该优先级级别用有界系统时间代替。请注意,在这种情况下,不仅可以抢先使用锁具,还可以中断旋转器。通常这不是问题,因为您对此无能为力。

答案 6 :(得分:-6)

  

在单核/单CPU系统上使用自旋锁通常没有意义,因为只要自旋锁轮询阻塞唯一可用的CPU核心,就不能运行其他线程,因为没有其他线程可以运行,所以锁也不会被解锁。 IOW,一个自旋锁只会在这些系统上浪费CPU时间而没有真正的好处

这是错误的。在uni处理器系统上使用自旋锁时没有浪费cpu周期,因为一旦进程进行自旋锁定,就会禁用抢占,因此,没有其他人在旋转!只是使用它没有任何意义!因此,内核在编译时将preimpt_disable替换为Uni系统上的自旋锁!