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

定义一个 a=1; 然后起三个线程去执行 a=a+1; 那么最终的执行结果会是什么呢?

  •  
  •   shunfy · 2021-03-19 12:06:29 +08:00 · 4009 次点击
    这是一个创建于 1344 天前的主题,其中的信息可能已经有所发展或是发生改变。
    第 1 条附言  ·  2021-03-19 18:05:06 +08:00
    经过测试, 如果直接启动 3 个线程,都是执行 a=a+1 等待一段时间输出的结果一直为 4. 如果在每个执行线程启动后都立即启动另外的其他业务线程, 那么多次尝试等待输出的结果是 2. 不同的 CPU 数量应该也会影响结果, 再有些特殊的情况下, 可能会出现 3 的情况.
    27 条回复    2021-03-20 14:28:55 +08:00
    yamasa
        1
    yamasa  
       2021-03-19 12:16:48 +08:00
    你需要补充多线程和并行的基础知识。答案是 unknown,根据 cpu 调度,1-4 之间全部可能。
    Chenamy2017
        2
    Chenamy2017  
       2021-03-19 12:29:02 +08:00
    这不是操作系统里面并发的基本例子吗,自己跑一下比你问强多了。
    nightwitch
        3
    nightwitch  
       2021-03-19 12:29:15 +08:00   ❤️ 1
    未定义行为
    ingin
        4
    ingin  
       2021-03-19 12:42:09 +08:00 via Android
    @yamasa 我觉得是 2-4 之间
    pkwenda
        5
    pkwenda  
       2021-03-19 12:57:16 +08:00
    @ingin #4 you are right
    yamasa
        6
    yamasa  
       2021-03-19 13:06:19 +08:00
    @ingin 对 我脑抽了。
    CEBBCAT
        7
    CEBBCAT  
       2021-03-19 13:11:21 +08:00 via Android
    涉及可重入性,单纯地问答案其实没有什么意义
    webcoder
        8
    webcoder  
       2021-03-19 14:11:40 +08:00
    不作线程锁的话,2-4 都有可能。
    ch2
        9
    ch2  
       2021-03-19 14:17:29 +08:00

    结果为 4 的可能性是最大的,2 和 3 的情况比 segement fault 还要罕见
    beat
        10
    beat  
       2021-03-19 14:23:00 +08:00
    做好并发控制,答案就是 4
    gdt
        11
    gdt  
       2021-03-19 14:37:36 +08:00
    随机的
    xuanbg
        12
    xuanbg  
       2021-03-19 14:47:55 +08:00
    等待足够的时间,a 就是 4 。
    hauibojek
        13
    hauibojek  
       2021-03-19 15:03:12 +08:00
    都执行完不是 4 吗。
    cxe2v
        14
    cxe2v  
       2021-03-19 15:08:09 +08:00
    a=a+1 够复杂耗时的话,结果应该就会有明显差异了
    hejw19970413
        15
    hejw19970413  
       2021-03-19 15:30:38 +08:00
    这个 都有可能。
    nullllllllllllll
        16
    nullllllllllllll  
       2021-03-19 15:51:22 +08:00
    首先我们排除掉 0[狗头]
    norz
        17
    norz  
       2021-03-19 16:18:35 +08:00
    @nullllllllllllll 再排除掉 1[狗头]
    faceRollingKB
        18
    faceRollingKB  
       2021-03-19 16:23:08 +08:00
    读 1 、写 1 、读 2 、写 2 、读 3 、写 3

    除了读 n 位于写 n 之前外其他操作随机排列组合,就可以得出所有可能的结果
    realpg
        19
    realpg  
       2021-03-19 16:36:18 +08:00
    现代计算机,没特殊情况,99%可能是 4

    当然你要起十万个线程就不可能正好
    mingl0280
        20
    mingl0280  
       2021-03-19 17:23:33 +08:00 via Android
    那要看你用的是 atomic 还是非 atomic 的,算法有没有加锁等等情况,atomic/正确加锁的就是 4,其他的随机 2-4 都有可能。
    SWBMESSI
        21
    SWBMESSI  
       2021-03-19 17:40:43 +08:00
    count1: 0
    count2: 29
    count3: 1539222
    count4: 32334689

    用 go 程试了一下
    ns09005264
        22
    ns09005264  
       2021-03-19 18:01:13 +08:00
    ![image.png]( https://i.loli.net/2021/03/19/NzQfkTFAnZYt5lc.png)
    刚学 go,这样写对不对,这个模拟的是不加锁的效果
    hello2060
        23
    hello2060  
       2021-03-19 18:07:24 +08:00 via iPhone
    @hauibojek 第一个把 a 读出来的最后一个写回去咋办
    w99wjacky
        24
    w99wjacky  
       2021-03-19 18:21:41 +08:00
    如果 a 是基本数据类型,多核 cpu 空载下大概率是 2
    但是本身这个写法结果是不可预知的。
    no1xsyzy
        25
    no1xsyzy  
       2021-03-19 18:28:11 +08:00   ❤️ 1
    欢迎投入 ponylang 怀抱,答案是“你不可能让两个 actor 同时写,没有一个 capability 支持这样操作”
    ch2
        26
    ch2  
       2021-03-20 01:23:16 +08:00 via iPhone
    @w99wjacky 线程的启动依赖于 OS 调度,有先后顺序,3 个线程同时读到 a=1 是非常小概率的事
    xingheng
        27
    xingheng  
       2021-03-20 14:28:55 +08:00
    没有说语言环境,没有说 a 是局部还是全局变量,连示例代码都没有,猜毛线?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5267 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 06:00 · PVG 14:00 · LAX 22:00 · JFK 01:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.