16

请解释为什么Busy Waiting通常不受欢迎,而Spinning通常被认为是可以的。据我所知,它们都无限循环,直到满足某些条件。

4

3 回答 3

11

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

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

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

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

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

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

(请注意,“无锁”和“无等待”在学术环境中的使用略有不同,请参阅维基百科关于非阻塞算法的文章。)

于 2016-07-03T18:36:13.147 回答
0

标准互斥锁与自旋互斥锁:当线程调用锁定并获取互斥锁的函数时,该函数在互斥锁被锁定之前不会返回。这对于事件同步来说很典型:一个线程等待一个事件,即它已经获得互斥体所有权这一事实。发生这种情况有两种方式:

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

• 忙等待,也称为自旋等待,其中等待锁定互斥锁的线程不会释放 CPU。它保持调度,执行一些琐碎的无操作指令,直到互斥锁被释放。

标准互斥锁通常订阅第一个策略,并执行空闲等待。但是一些库也提供了订阅自旋等待策略的互斥锁。最好的一个取决于应用程序上下文。对于非常短的等待,在用户空间中旋转会更有效,因为将线程置于阻塞状态需要循环。但是对于长时间的等待,睡眠线程会释放其 CPU,从而使其他线程可以使用周期

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

于 2021-08-09T12:55:51.173 回答
-2

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

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

  1. 对于具有超线程的 CPU,一个忙于等待的线程可能会饿死同一物理内核中的另一个线程,甚至是它正在等待的线程。
  2. 当您忙于等待时,当您终于得到您正在等待的资源时,您会选择所有错误预测分支的母亲。
  3. 忙于等待会干扰 CPU 电源管理。
  4. 繁忙的等待会使内核间总线饱和,因为您不断检查的内容会导致缓存同步流量。

但是设计自旋锁的人了解所有这些问题,并且确切地知道如何在平台上缓解这些问题。他们不会编写幼稚的旋转代码,而是编写智能旋转代码。

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

于 2016-07-03T19:26:00.080 回答