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


当前回答

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

这是错误的。在单处理器系统上使用自旋锁不会浪费cpu周期,因为一旦一个进程使用了自旋锁,抢占就被禁用了,因此,就不会有其他进程自旋了!只是使用它没有任何意义!因此,在Uni系统上的自旋锁被内核在编译时用preempt_disable代替!

其他回答

自旋锁和互斥锁同步机制现在非常常见。

让我们首先考虑Spinlock。

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

通常,最直观的想法是通过一个变量来处理同步,以保护临界区。互斥锁的概念是相似的,但它们仍然是不同的。重点关注:CPU利用率。自旋锁需要消耗CPU时间来等待执行操作,因此,我们可以总结两者之间的差异:

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

在Windows中,使用Spinlock会将线程升级到DISPATCH_LEVEL,这在某些情况下可能是不允许的,所以这次我们必须使用互斥锁(APC_LEVEL)。

还请注意,在某些环境和条件下(例如在调度级别>= dispatch level的windows上运行),您不能使用互斥,而应该使用自旋锁。 在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

梅基的回答非常准确。然而,在单个处理器上,当任务等待中断服务例程提供的锁时,使用自旋锁可能是有意义的。中断将控制权传递给ISR, ISR将准备好资源供等待任务使用。在将控制权交还给被中断的任务之前,它将以释放锁结束。旋转任务将发现自旋锁可用并继续。

继续Mecki的建议,Alexander Sandler的博客,Alex on Linux上的文章pthread互斥锁vs pthread自旋锁展示了如何使用#ifdef实现自旋锁和互斥锁来测试行为。

但是,一定要根据你的观察来做最后的决定,理解正如所举的例子是一个孤立的案例,你的项目要求、环境可能完全不同。

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

这是错误的。在单处理器系统上使用自旋锁不会浪费cpu周期,因为一旦一个进程使用了自旋锁,抢占就被禁用了,因此,就不会有其他进程自旋了!只是使用它没有任何意义!因此,在Uni系统上的自旋锁被内核在编译时用preempt_disable代替!