多线程小问题求教

2019-01-21 23:11:15 +08:00
 Counter
线程 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

请问一般用什么方式处理这种问题?
2404 次点击
所在节点    程序员
16 条回复
lhx2008
2019-01-21 23:14:57 +08:00
为什么想不开要一直改成 0 呢,执行顺序确实是无法保证的,除非你 synchronize 一下了
niubee1
2019-01-21 23:25:21 +08:00
搞不清楚你的描述, 你到底是遇到了这样的问题, 还是想要实现这样的效果
很显然 a 是两个线程的临界区, 对临界区的访问不做同步不加锁, 那么临界区就不是线程安全的, 啥情况都有可能产生, 如果是线程安全的, 那么无论是同步还是加锁都是可控的. 我觉得楼主要加强一下语文才是王道
leoleoasd
2019-01-21 23:25:27 +08:00
glacer
2019-01-22 00:11:11 +08:00
不对吧,就算没有第二个线程把 a = -1,a 在为 2 的时候变成 0,下一个循环的时候不还是执行代码 1 吗?
Counter
2019-01-22 05:43:27 +08:00
@niubee1 是遇到了这样的问题
ryd994
2019-01-22 06:38:33 +08:00
要么加普通锁,要么用 RCU 或硬件原子操作。
@glacer 我感觉这段代码的目的是执行且只执行一次代码 1。只有 a==-1 时会执行一次。他描述的这种情况,就把一次执行漏掉了。
stebest
2019-01-22 09:37:20 +08:00
你这样开线程又没有先后顺序,要么 join,要么 wait,你要想先执行线程 1 一次,直接写在主线程就好。
jifengg
2019-01-22 09:55:16 +08:00
首先,你描述的问题确实挺奇怪。
其次,线程间要保持数据一致性,可以用锁,具体看各种语言的实现。
最后,祝你顺利解决问题。
PPing520
2019-01-22 10:04:27 +08:00
而接着在线程 1 的 if 块代码又把 a 改为 0。这样下一个循环的时候不就已经走到执行代码片段 1,哪来的走到执行 a = 0?楼主是不是表达错了意思?
PPing520
2019-01-22 10:07:25 +08:00
我也不管你到底意思是啥,,说白了这就是个普通的线程安全问题,你得分清哪些是临界区的代码,在进临界区和出临界区的时候加锁即可
fromxt
2019-01-22 10:56:31 +08:00
感觉线程 1 的目的就是 a=-1 执行以下代码 1,但是线程 2 可能在 if els 执行中改变 a 的值,那就把 if ... else ... 这段加一个互斥锁 mutex,保证执行完之后,再对 a 进行修改。
VictorJing94
2019-01-22 11:22:34 +08:00
...线程二存在的意义是什么..
richieboy
2019-01-22 11:22:46 +08:00
a 加上 volatile 修饰
Raymon111111
2019-01-22 11:28:37 +08:00
用锁
fano
2019-01-22 17:06:34 +08:00
老老实实用锁。
www5070504
2019-01-22 17:23:44 +08:00
用锁用事件都行

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/529287

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX