我认为两者都在做同样的工作,您如何决定使用哪一个进行同步呢?
当前回答
使用自旋锁的规则很简单:当且仅当锁持有的实际时间有界且足够小时使用自旋锁。
注意,通常用户实现的自旋锁不满足这个要求,因为它们不禁用中断。除非禁用了抢占,否则在自旋锁进行时进行抢占违反了有限时间要求。
足够小是一种判断,取决于上下文。
例外:一些内核编程即使在时间没有限制的情况下也必须使用自旋锁。特别是如果CPU没有工作要做,它别无选择,只能旋转,直到有更多的工作出现。
Special danger: in low level programming take great care when multiple interrupt priorities exist (usually there is at least one non-maskable interrupt). In this higher priority pre-emptions can run even if interrupts at the thread priority are disabled (such as priority hardware services, often related to the virtual memory management). Provided a strict priority separation is maintained, the condition for bounded real time must be relaxed and replaced with bounded system time at that priority level. Note in this case not only can the lock holder be pre-empted but the spinner can also be interrupted; this is generally not a problem because there's nothing you can do about it.
其他回答
还请注意,在某些环境和条件下(例如在调度级别>= 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
继续Mecki的建议,Alexander Sandler的博客,Alex on Linux上的文章pthread互斥锁vs pthread自旋锁展示了如何使用#ifdef实现自旋锁和互斥锁来测试行为。
但是,一定要根据你的观察来做最后的决定,理解正如所举的例子是一个孤立的案例,你的项目要求、环境可能完全不同。
在单核/单CPU系统上使用自旋锁通常没有意义,因为只要自旋锁轮询阻塞了唯一可用的CPU核心,就没有其他线程可以运行,而且由于没有其他线程可以运行,锁也不会被解锁。低,自旋锁只在这些系统上浪费CPU时间,没有真正的好处
这是错误的。在单处理器系统上使用自旋锁不会浪费cpu周期,因为一旦一个进程使用了自旋锁,抢占就被禁用了,因此,就不会有其他进程自旋了!只是使用它没有任何意义!因此,在Uni系统上的自旋锁被内核在编译时用preempt_disable代替!
使用自旋锁的规则很简单:当且仅当锁持有的实际时间有界且足够小时使用自旋锁。
注意,通常用户实现的自旋锁不满足这个要求,因为它们不禁用中断。除非禁用了抢占,否则在自旋锁进行时进行抢占违反了有限时间要求。
足够小是一种判断,取决于上下文。
例外:一些内核编程即使在时间没有限制的情况下也必须使用自旋锁。特别是如果CPU没有工作要做,它别无选择,只能旋转,直到有更多的工作出现。
Special danger: in low level programming take great care when multiple interrupt priorities exist (usually there is at least one non-maskable interrupt). In this higher priority pre-emptions can run even if interrupts at the thread priority are disabled (such as priority hardware services, often related to the virtual memory management). Provided a strict priority separation is maintained, the condition for bounded real time must be relaxed and replaced with bounded system time at that priority level. Note in this case not only can the lock holder be pre-empted but the spinner can also be interrupted; this is generally not a problem because there's nothing you can do about it.
自旋锁和互斥锁同步机制现在非常常见。
让我们首先考虑Spinlock。
基本上,它是一个忙碌的等待操作,这意味着我们必须等待指定的锁被释放,然后才能继续进行下一个操作。概念上很简单,但实现起来却不是那么回事。例如:如果锁还没有释放,那么线程已经被换出并进入睡眠状态,我们应该处理它吗?当两个线程同时请求访问时,如何处理同步锁?
通常,最直观的想法是通过一个变量来处理同步,以保护临界区。互斥锁的概念是相似的,但它们仍然是不同的。重点关注:CPU利用率。自旋锁需要消耗CPU时间来等待执行操作,因此,我们可以总结两者之间的差异:
在同构多核环境中,如果在临界区花费的时间较小,则使用Spinlock,因为我们可以减少上下文切换时间。(单核比较不重要,因为有些系统在中间实现Spinlock开关)
在Windows中,使用Spinlock会将线程升级到DISPATCH_LEVEL,这在某些情况下可能是不允许的,所以这次我们必须使用互斥锁(APC_LEVEL)。
推荐文章
- 为什么pthreads的条件变量函数需要互斥?
- 并发HashSet<T>在。net框架?
- 在Objective-C中@synchronized如何锁定/解锁?
- 同步vs锁定
- 互斥实例/教程?
- 在Swift中,什么相当于Objective-C的“@synchronized”?
- 原子/ volatile / synchronized之间的区别是什么?
- java的synchronized关键字的c#版本?
- 什么时候应该使用自旋锁而不是互斥锁?
- 避免在Java中同步(这)?
- 在c#中使用全局互斥锁的好模式是什么?
- 锁,互斥和信号量之间的区别是什么?
- lock语句在底层做什么?
- 创建单实例WPF应用程序的正确方法是什么?
- 什么是互斥量?