可能的重复:
为什么持有自旋锁时不能睡觉? https://stackoverflow.com/questions/4752031/why-cant-you-sleep-while-holding-spinlock
据我所知,自旋锁应该在短时间内使用,并且只是代码中的选择,例如不允许休眠(抢占)的中断处理程序。
但是,我不知道为什么有这样一个“规则”,即在持有自旋锁时根本不应该睡觉。我知道这不是推荐的做法(因为它对性能有害),但我认为没有理由在自旋锁中不允许睡眠。
获取信号量时不能持有自旋锁,因为在等待信号量时可能必须休眠,并且持有自旋锁时不能休眠(来自 Robert Love 的《Linux 内核开发》)。
我能看到的唯一原因是出于可移植性的原因,因为在单处理器中,自旋锁被实现为禁用中断,并且通过禁用中断,睡眠当然是不允许的(但睡眠不会破坏SMP系统中的代码)。
但我想知道我的推理是否正确,或者是否还有其他原因。
至少在 Linux 中,不允许在自旋锁中休眠有几个原因:
- 如果线程 A 在自旋锁中休眠,然后线程 B 尝试获取相同的自旋锁,则单处理器系统将发生死锁。线程 B 永远不会进入睡眠状态(因为自旋锁没有在 A 完成时唤醒 B 所需的等待列表),并且线程 A 永远不会有机会醒来。
- 使用自旋锁而不是信号量正是因为它们更高效 -provided你们不会争太久。允许睡眠意味着您将有很长的争用期,从而消除了使用自旋锁的所有好处。在这种情况下,仅使用信号量您的系统会更快。
- 自旋锁通常用于与中断处理程序同步,通过此外禁用中断。如果您处于睡眠状态,则此用例是不可能的(一旦进入中断处理程序,您就无法切换回线程以让它唤醒并完成其自旋锁关键部分)。
使用正确的工具完成正确的工作 - 如果您需要睡觉,信号量和互斥体就是您的朋友。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)