问一个并发相关的问题

2018-11-16 17:03:27 +08:00
 zhaogaz

最近看了看并发编程相关的东西,看到了一个东西叫做无锁,原理大概就是反复重试,直到能修改,大部分人都说,这个能节省线程挂起的时间消耗.

也就是说,对于无锁来说,就是两个线程不停地执行

但是 cpu 在执行多个线程的时候,不也是不停的做 context switch 上下文切换么?


假设有两个线程

情况 1:这两个线程使用无锁的方式获取一个资源,在 cpu 层面,这两个线程就是各执行一会.不停地做上下文切换.

情况 2:这两个线程使用一个读锁获取一个资源,其中一个线程拿到锁了,另一个阻塞等待.在 cpu 层面,那不就是一个线程一直执行么?不存在上下文切换了.


所以为什么都说无锁效果更好?我的理解到底哪里错了?问题出在哪?

2766 次点击
所在节点    Java
7 条回复
lurenw
2018-11-16 17:20:22 +08:00
ffeii
2018-11-16 17:23:23 +08:00
线程阻塞的多了就没有线程去处理请求了,并发就上不去
sagaxu
2018-11-16 19:19:37 +08:00
1. 这两个线程一直在做 cas,不会暂停,也没有上下文切换。
2. 锁并不都是互斥的,没拿到锁被阻塞的线程,会从 CPU 的 running 队列剥离,有上下文切换。

lock free 不是绝对的好,有它自己的适用场景。lock free 优点是 cost 很小,缺点是竞争激烈时不断重试占用了 CPU。

某些系统实现,轻锁在遇到竞争时,膨胀成重锁。
zhaogaz
2018-11-16 23:51:00 +08:00
@sagaxu 单核 CPU 上运行的多线程程序, 同一时间只能一个线程在跑, 系统帮你切换线程而已, 系统给每个线程分配时间片来执行——我指的是这个上下文切换

那两个线程不就是一直在做切换么?
sagaxu
2018-11-17 01:22:07 +08:00
@zhaogaz cpu 时间片通常是毫秒级的,lock free 持有锁到解锁之间的时间间隔通常是纳秒级的,在 A 线程占用 CPU 的时候,他都够锁和解锁上百万次了,lockfree 并没有带来更多的上下文切换。
luozic
2018-11-17 13:29:55 +08:00
现在不是推 IO 多路复用么。实际线程上的多路复用就是纤程,但是这些东西都是解决 IO 资源问题的,如果是计算为主的程序,切换线程屁用没有反而大大减速。 根据功能特点合理规划并发方式。 进程 线程 fiber 是一脉相承,ringbuffer akka 是另外一种套路。
dahai1990
2018-12-03 11:20:07 +08:00
@zhaogaz 你说的是在单核 CPU 上,在多核 CPU 上,多个线程同时执行,就没有上下文切换了。

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

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

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

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

© 2021 V2EX