自旋锁仅在具有真正并行性的系统上有效,即多核/处理器系统。由于他们的设计,这并不奇怪。
但是,共享资源的线程必须在不同的核心上执行。否则情况类似于单处理器系统。
只是概率问题或调度程序试图将互锁线程放在不同的CPU上以提供真正的并发性吗?
答案 0 :(得分:5)
线程上下文切换的成本是自旋锁有用的原因。对于Windows上的交换机,引用的通常数字是2000到10,000个cpu周期。由于保证的高速缓存未命中而必须存储和重新加载处理器状态和停顿所关联的成本。这是纯粹的开销,没有什么用处。
因此,如果程序等待锁定变为可用,烧毁数千个周期并定期尝试进入锁定,则程序可以执行得更好。如果预计锁可以快速获得,则可以避免上下文切换。
没有可用于等待如此短暂持续时间的计时器,它通过实际燃烧具有小循环的循环来实现。纺纱。这在处理器级别受支持,专用的PAUSE机器代码指令可用于降低在Intel / AMD内核上旋转时消耗的功率。 .NET中的Thread.Yield()和Thread.SpinWait()利用它。
实际上在代码中有效使用自旋锁可能很棘手,当然只有获得锁的几率足够高才能正常工作。如果它们不是那么自旋锁是主动有害的,因为它延迟了一个上下文切换,一个可能需要让另一个线程重新获得处理器并释放锁。 .NET 4.0 SpinLock类很有用,它为失败的旋转生成ETW events。否则well documented。
答案 1 :(得分:1)
当涉及两个线程时,自旋锁可能是有效的,因为当一个线程在等待时,另一个线程释放锁。因此,你是正确的,没有保证,并且涉及很多概率。因此,您只能使用保持很短时间的锁来等待具有螺旋锁的锁。因为获取锁的线程显然是在获取锁时执行的,所以如果该线程在非常短的时间内保持锁,则线程仍然很可能执行释放锁。
然而,当涉及IO时,自旋锁也可能是有效的,即当线程没有在另一个线程上等待时,但是在硬件事件上发出信号表示数据正在进入,特别是如果很快就会预期该数据(例如,等待正在执行的硬件功能。)