最近看了看并发编程相关的东西,看到了一个东西叫做无锁,原理大概就是反复重试,直到能修改,大部分人都说,这个能节省线程挂起的时间消耗.
也就是说,对于无锁来说,就是两个线程不停地执行
但是 cpu 在执行多个线程的时候,不也是不停的做 context switch 上下文切换么?
假设有两个线程
情况 1:这两个线程使用无锁的方式获取一个资源,在 cpu 层面,这两个线程就是各执行一会.不停地做上下文切换.
情况 2:这两个线程使用一个读锁获取一个资源,其中一个线程拿到锁了,另一个阻塞等待.在 cpu 层面,那不就是一个线程一直执行么?不存在上下文切换了.
所以为什么都说无锁效果更好?我的理解到底哪里错了?问题出在哪?
1
lurenw 2018-11-16 17:20:22 +08:00 1
|
2
ffeii 2018-11-16 17:23:23 +08:00 via iPhone 1
线程阻塞的多了就没有线程去处理请求了,并发就上不去
|
3
sagaxu 2018-11-16 19:19:37 +08:00 via Android 2
1. 这两个线程一直在做 cas,不会暂停,也没有上下文切换。
2. 锁并不都是互斥的,没拿到锁被阻塞的线程,会从 CPU 的 running 队列剥离,有上下文切换。 lock free 不是绝对的好,有它自己的适用场景。lock free 优点是 cost 很小,缺点是竞争激烈时不断重试占用了 CPU。 某些系统实现,轻锁在遇到竞争时,膨胀成重锁。 |
4
zhaogaz OP |
5
sagaxu 2018-11-17 01:22:07 +08:00 via Android 1
@zhaogaz cpu 时间片通常是毫秒级的,lock free 持有锁到解锁之间的时间间隔通常是纳秒级的,在 A 线程占用 CPU 的时候,他都够锁和解锁上百万次了,lockfree 并没有带来更多的上下文切换。
|
6
luozic 2018-11-17 13:29:55 +08:00 via iPhone 2
现在不是推 IO 多路复用么。实际线程上的多路复用就是纤程,但是这些东西都是解决 IO 资源问题的,如果是计算为主的程序,切换线程屁用没有反而大大减速。 根据功能特点合理规划并发方式。 进程 线程 fiber 是一脉相承,ringbuffer akka 是另外一种套路。
|