为什么在握住自旋锁时不允许"睡觉"?[英] Why is "sleeping" not allowed while holding a spinlock?

本文是小编为大家收集整理的关于为什么在握住自旋锁时不允许"睡觉"?的处理方法,想解了为什么在握住自旋锁时不允许"睡觉"?的问题怎么解决?为什么在握住自旋锁时不允许"睡觉"?问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

可能的重复:
为什么您在举行Spinlock时不能睡觉?

据我所知,据我所知,Spinlock应该在短时间内使用,并且仅是代码中的选择,例如不允许睡觉的中断处理程序(抢占).

但是,我不知道为什么有这样的"规则",以至于握着双手锁时根本不睡觉.我知道这不是推荐的做法(因为表现有害),但是我认为不应在旋转锁中允许睡眠.

您在获得信号量时不能握住旋转锁,因为您可能在等待信号量时必须睡觉,并且在握住旋转锁时无法入睡(来自Robert Love的" Linux内核开发").

我能看到的唯一原因是出于可移植性原因,因为在单层处理器中,Spinlock被实现为禁用中断,并且通过禁用中断,睡眠当然是不允许的(但是睡觉不会破坏SMP系统中的代码).

,但我想知道我的推理是否正确或是否还有其他原因.

推荐答案

至少在Linux中,不允许在Spinlock中睡觉:

有几个原因:

  1. 如果螺纹A在单独的锁中睡觉,然后螺纹B然后尝试获得相同的自旋锁,则单层处理器系统将死亡.线程B永远不会入睡(因为Spinlocks完成A完成后没有唤醒B的候补名单),并且线程A永远不会有机会醒来.
  2. Spinlock恰恰是在信号量上使用的,这是因为它们更有效 - 提供了您不长的竞争.允许睡觉意味着您将有很长的争夺期,从而消除了使用Spinlock的所有好处.在这种情况下,您的系统只会使用信号量更快.
  3. Spinlock通常通过 禁用中断来与中断处理程序同步.如果您睡觉,则无法使用此用例(一旦进入中断处理程序,就无法切换到线程以使其醒来并完成其Spinlock关键部分).

使用合适的工作工具 - 如果您需要睡觉,信号量和静音是您的朋友.

其他推荐答案

  • 实际上,您 can 睡眠中断或其他类型的排除活动.如果不这样做,您睡觉的状况可能会因中断而改变状态,那么您将永远不会醒来.如果没有提高优先级或其他一些关键部分,则无法输入睡眠代码,该部分封闭了决定睡眠和上下文开关之间的执行路径.

  • 但是,对于锁定的锁定,睡眠是一场灾难.其他线程撞到它时会旋转,直到您从睡眠中醒来之前,它们不会停止旋转.与在最坏情况下,在一个自旋锁中预期的少量旋转相比,这可能是永恒的,因为Spinlock只是为了同步对内存位置的访问,它们不应该与上下文切换机制相互作用.

    (为此,其他所有线程最终都可能击中自旋锁,然后您将楔入整个系统的每个核心的每个线程.)

其他推荐答案

当您使用旋转锁定时,您将无法使用.在真正必要的地方使用旋转锁来保护关键区域和共享数据结构.如果您在还持有信号量的同时获得了一个,则可以将锁定到任何关键区域(例如)附加到(通常是特定较大数据结构的成员),同时允许此过程可能入睡.例如,如果在此过程入睡时会增加IRQ,并且IRQ处理程序需要访问仍然被锁定的关键区域,则它已被阻塞,IRQ永远不会发生这种情况.显然,您可以构成未使用旋转锁定的示例(假设的旋转锁,例如NOP循环);但这根本不是Linux内核中发现的真正的自旋锁.

本文地址:https://www.itbaoku.cn/post/359076.html