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

多线程小问题求教

  •  
  •   Counter · 2019-01-21 23:11:15 +08:00 via iPhone · 2411 次点击
    这是一个创建于 2136 天前的主题,其中的信息可能已经有所发展或是发生改变。
    线程 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
        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   ·   实用小工具   ·   5450 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 46ms · UTC 06:59 · PVG 14:59 · LAX 22:59 · JFK 01:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.