V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zhaogaz
V2EX  ›  Java

问一个并发相关的问题

  •  
  •   zhaogaz · 2018-11-16 17:03:27 +08:00 · 2557 次点击
    这是一个创建于 1960 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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


    假设有两个线程

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

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


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

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

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

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

    那两个线程不就是一直在做切换么?
    sagaxu
        5
    sagaxu  
       2018-11-17 01:22:07 +08:00 via Android   ❤️ 1
    @zhaogaz cpu 时间片通常是毫秒级的,lock free 持有锁到解锁之间的时间间隔通常是纳秒级的,在 A 线程占用 CPU 的时候,他都够锁和解锁上百万次了,lockfree 并没有带来更多的上下文切换。
    luozic
        6
    luozic  
       2018-11-17 13:29:55 +08:00 via iPhone   ❤️ 2
    现在不是推 IO 多路复用么。实际线程上的多路复用就是纤程,但是这些东西都是解决 IO 资源问题的,如果是计算为主的程序,切换线程屁用没有反而大大减速。 根据功能特点合理规划并发方式。 进程 线程 fiber 是一脉相承,ringbuffer akka 是另外一种套路。
    dahai1990
        7
    dahai1990  
       2018-12-03 11:20:07 +08:00
    @zhaogaz 你说的是在单核 CPU 上,在多核 CPU 上,多个线程同时执行,就没有上下文切换了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2743 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 12:45 · PVG 20:45 · LAX 05:45 · JFK 08:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.