Spinlock与忙碌的等待

时间:2016-06-30 13:16:59

标签: spinlock busy-waiting

请解释为什么忙碌等待通常不赞成,而 Spinning 通常被视为没问题。据我所知,他们都无限循环,直到满足某些条件。

3 个答案:

答案 0 :(得分:9)

当资源争用较少时,通常会使用自旋锁,因此CPU只会进行几次迭代才能继续进行生产性工作。但是,锁定功能的库实现通常使用自旋锁定,然后是常规锁定。如果无法在合理的时间范围内获取资源,则使用常规锁定。这样做是为了通过快速获取锁定的设置中的上下文切换来减少开销。

术语忙等待往往意味着您愿意旋转并等待硬件寄存器或内存位置的更改。该术语并不一定意味着锁定,但它确实意味着在紧密的循环中等待,反复探测变化。

您可能希望使用忙等待,以便检测您想立即响应的环境中的某种更改。因此,使用忙等待实现自旋锁。繁忙等待在任何情况下都非常有用,其中非常低延迟的响应比浪费CPU周期更重要(如某些类型的嵌入式编程)。

与此相关的术语是“无锁”和“无等待”:

所谓的无锁算法倾向于使用紧急忙等待与CAS指令,但争用是在普通情况下如此之低,以至于CPU通常只需要迭代几次。

所谓的等待算法根本不会做任何繁忙的等待。

(请注意,«lock-free»和«wait-free»在学术环境中的使用略有不同,请参阅维基百科关于Non-blocking algorithms的文章。)

答案 1 :(得分:0)

<块引用>

标准与自旋互斥体:当线程调用函数时, 锁定并获取互斥锁,该函数直到 互斥锁被锁定。这是典型的事件同步:一个线程 等待一个事件,即它已获得互斥锁的事实 所有权。发生这种情况的方式有两种:

• 空闲等待:等待锁定互斥锁的线程被阻塞在一个 等待状态如第 2 章所述。它释放 CPU,它可以 然后用于运行另一个线程。当互斥锁可用时, 运行时系统唤醒并重新调度等待线程, 然后可以锁定现在可用的互斥锁。

• 忙等待,也称为自旋等待,其中线程等待 锁定互斥锁不会释放 CPU。它仍然被安排, 执行一些微不足道的什么都不做的指令,直到互斥锁 发布。

标准互斥体通常订阅第一个策略,并执行 一个空闲的等待。但是一些库也提供订阅的互斥锁 到旋转等待策略。最好的取决于应用 语境。对于在用户空间中旋转的非常短的等待,效率更高 因为将线程置于阻塞状态需要循环。但 对于长时间等待,睡眠线程释放其 CPU 制作周期 可用于其他线程

我发现这与此来源非常相关:https://www.sciencedirect.com/topics/computer-science/waiting-thread

答案 2 :(得分:-2)

当您了解规则的确切原因并拥有详细的平台和应用知识时,您就知道何时违反该规则是恰当的。自旋锁由专家实施,他们完全了解他们正在开发的平台以及自旋锁的预期应用。

繁忙等待的问题很多,但在大多数平台上,都有解决方案。问题包括:

  1. 对于具有超线程的CPU,忙碌等待的线程可能会使同一物理核心中的另一个线程饿死,即使是它正在等待的线程。
  2. 当你忙着等待,当你终于得到你正在等待的资源时,你会把所有错误预测的分支的母亲带走。
  3. 忙碌的等待会干扰CPU电源管理。
  4. 忙碌的等待可能会使核心间总线饱和,因为您继续检查会导致缓存同步流量。
  5. 但设计螺旋锁的人了解所有这些问题,并确切地知道如何在平台上缓解它们。他们没有编写天真的旋转代码,他们编写智能旋转代码。

    所以是的,它们都无限循环,直到满足某些条件,但它们以不同的方式循环