多线程小问题求教 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
Counter
V2EX    程序员

多线程小问题求教

  •  
  •   Counter 2019-01-21 23:11:15 +08:00 via iPhone 2679 次点击
    这是一个创建于 2454 天前的主题,其中的信息可能已经有所发展或是发生改变。
    线程 1,执行代码:
    while(true){
    if(a!=-1){
    a=0;
    }
    else{
    /*代码片段 1*/
    }
    }

    线程 2,执行代码:
    /*代码片段 2*/
    a=-1;

    有可能出现一种情况,a 初始值为 2,当线程 1 执行完 if(a!=-1)后极短时间内,线程 2 把 a 改为-1,而接着在线程 1 的 if 块代码又把 a 改为 0。在下一次循环时,原设想是执行代码片段 1,却变成执行 a=0

    请问一般用什么方式处理这种问题?
    16 条回复    2019-01-22 17:23:44 +08:00
    lhx2008
        1
    lhx2008  
       2019-01-21 23:14:57 +08:00 via Android
    为什么想不开要一直改成 0 呢,执行顺序确实是无法保证的,除非你 synchronize 一下了
    niubee1
        2
    niubee1  
       2019-01-21 23:25:21 +08:00   1
    搞不清楚你的描述, 你到底是遇到了这样的问题, 还是想要实现这样的效果
    很显然 a 是两个线程的临界区, 对临界区的访问不做同步不加锁, 那么临界区就不是线程安全的, 啥情况都有可能产生, 如果是线程安全的, 那么无论是同步还是加锁都是可控的. 我觉得楼主要加强一下语文才是王道
    leoleoasd
        3
    leoleoasd  
       2019-01-21 23:25:27 +08:00   1
    glacer
        4
    glacer  
       2019-01-22 00:11:11 +08:00
    不对吧,就算没有第二个线程把 a = -1,a 在为 2 的时候变成 0,下一个循环的时候不还是执行代码 1 吗?
    Counter
        5
    Counter  
    OP
       2019-01-22 05:43:27 +08:00 via iPhone
    @niubee1 是遇到了这样的问题
    ryd994
        6
    ryd994  
       2019-01-22 06:38:33 +08:00   1
    要么加普通锁,要么用 RCU 或硬件原子操作。
    @glacer 我感觉这段代码的目的是执行且只执行一次代码 1。只有 a==-1 时会执行一次。他描述的这种情况,就把一次执行漏掉了。
    stebest
        7
    stebest  
       2019-01-22 09:37:20 +08:00
    你这样开线程又没有先后顺序,要么 join,要么 wait,你要想先执行线程 1 一次,直接写在主线程就好。
    jifengg
        8
    jifengg  
       2019-01-22 09:55:16 +08:00
    首先,你描述的问题确实挺奇怪。
    其次,线程间要保持数据一致性,可以用锁,具体看各种语言的实现。
    最后,祝你顺利解决问题。
    PPing520
        9
    PPing520  
       2019-01-22 10:04:27 +08:00
    而接着在线程 1 的 if 块代码又把 a 改为 0。这样下一个循环的时候不就已经走到执行代码片段 1,哪来的走到执行 a = 0?楼主是不是表达错了意思?
    PPing520
        10
    PPing520  
       2019-01-22 10:07:25 +08:00
    我也不管你到底意思是啥,,说白了这就是个普通的线程安全问题,你得分清哪些是临界区的代码,在进临界区和出临界区的时候加锁即可
    fromxt
        11
    fromxt  
       2019-01-22 10:56:31 +08:00   1
    感觉线程 1 的目的就是 a=-1 执行以下代码 1,但是线程 2 可能在 if els 执行中改变 a 的值,那就把 if ... else ... 这段加一个互斥锁 mutex,保证执行完之后,再对 a 进行修改。
    VictorJing94
        12
    VictorJing94  
       2019-01-22 11:22:34 +08:00
    ...线程二存在的意义是什么..
    richieboy
        13
    richieboy  
       2019-01-22 11:22:46 +08:00   1
    a 加上 volatile 修饰
    Raymon111111 /td>
        14
    Raymon111111  
       2019-01-22 11:28:37 +08:00   1
    用锁
    fano
        15
    fano  
       2019-01-22 17:06:34 +08:00   1
    老老实实用锁。
    www5070504
        16
    www5070504  
       2019-01-22 17:23:44 +08:00   1
    用锁用事件都行
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5513 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 90ms UTC 08:28 PVG 16:28 LAX 01:28 JFK 04:28
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86