假如 CPU 只有一个核心,使用 CAS 并发竞争的问题

2021-05-03 11:47:14 +08:00
 zhongpingjing
两个线程互相竞争,A 线程获取锁执行,B 线程通过自旋来获取锁。
cpu 只有一个核心,A 线程占用了 CPU,B 应该不能自旋了吧??是不是只能等 A 执行完毕
6571 次点击
所在节点    Java
72 条回复
ivechan
2021-05-07 22:11:39 +08:00
@fengjianxinghun 你发的链接恰好证明 Linus 是对的。
你难道没发现,你所发的代码,都特别注明,大部分情况下不要使用自旋锁吗?
在能够抢占或者中断的操作系统里,用户态自旋锁在很多情况下都毫无意义(只会浪费 CPU 时间)

“/*
* N.B. You most likely do _not_ want to use MicroSpinLock or any
* other kind of spinlock. Consider MicroLock instead.”
fengjianxinghun
2021-05-08 10:17:47 +08:00
@ivechan MicroLock 就是为了解决原始 spinlock 的问题。
fengjianxinghun
2021-05-08 10:20:58 +08:00
@ivechan MicroLock 之类的实现很接近 glibc 的 mutex 实现,先自旋计数,然后休眠让出 cpu 。
现在都是 2 种结合处理。
fengjianxinghun
2021-05-08 10:23:43 +08:00
@fengjianxinghun 你只要在用户态用了 mutex,其实你就用了 spinlock

https://code.woboq.org/userspace/glibc/nptl/pthread_mutex_lock.c.html
ivechan
2021-05-09 01:42:43 +08:00
@fengjianxinghun 你再仔细看看我说的话,和你说的话,确保你理解我的意思吧。
ivechan
2021-05-09 02:00:57 +08:00
@fengjianxinghun 在进入睡眠之前自旋一会尝试去获取锁那是因为有时候锁短时间内就能获取到,不必要走 slowpath,多了上下文切换等资源损耗。

这就是我说的"除非你真的知道你在做什么"的场景。
spinlock 没有问题,有问题用错场景的人。这里不是解决 spinlock 的问题,这里解决的是 muted lock 在发生竞争时 overhead 过多的问题。


你没必要再拿这种打自己脸的例子来解释了,用户态锁场景下 99%都不应该用 spinlock,就是事实。
说什么你用了 mutex 就是用了 spinlock 简直是偷换概念,胡搅蛮缠。



重要的事情说三遍:

N.B. You most likely do _not_ want to use MicroSpinLock or any
* other kind of spinlock. Consider MicroLock instead.”


N.B. You most likely do _not_ want to use MicroSpinLock or any
* other kind of spinlock. Consider MicroLock instead.”


N.B. You most likely do _not_ want to use MicroSpinLock or any
* other kind of spinlock. Consider MicroLock instead.”
fengjianxinghun
2021-05-09 18:59:19 +08:00
@ivechan 那就不用讨论了,任何用户态锁实现,都会 spinlock 提高节省性能,避免直接陷入 syscall futex 。你用 mutex 你代码天生就有 spinlock 。我犯得着和你纠缠?也不用说服你。
ivechan
2021-05-10 23:36:06 +08:00
N.B. You most likely do _not_ want to use MicroSpinLock or any
* other kind of spinlock. Consider MicroLock instead.”

你连英语都不懂吗。。。
aichunya
2021-05-11 12:05:41 +08:00
@lsylsy2 Q1 有个地方不知道是我理解偏差还是您写的不够清晰,CPU 只有一个核心的话,A 线程占用了 CPU,在这个时间片内,B 线程应该是不能自旋了吧,因为此时此刻 B 线程没有 CPU 的执行权,如果 B 线程要自旋,必须要等 CPU 分配到了时间片吧?
如果是我理解的话,倒是能理解你回答'可以'的含义了,如果不是的话,烦请再赐教(^_^)
lsylsy2
2021-05-11 15:39:51 +08:00
我来理一个单线程时间轴,以下每一行是一个时间片
T1 A 获取锁,做事情(没做完)
T2 B 自旋一整个时间片,一直失败
T3 A 做完了事情,释放锁
T4 B 自旋并一次成功,做事情
T5 B 做完事情,释放锁
lsylsy2
2021-05-11 15:40:03 +08:00
@aichunya 忘记 at 了,在上面一条
aichunya
2021-05-12 09:29:46 +08:00
@lsylsy2 谢谢解答,这样正好也理解了楼上各位说的,在单线程情况下,自旋锁是浪费 CPU 时间的,因为不管如何自旋,都要等拿了锁的那个线程执行完毕,把锁释放之后才能自旋成功获取到锁,因此不能说不可以用.

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/774722

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX