我有这两个函数,并行执行:
int x = 10 // a common variable
void P1(){ void P2(){
while(1){ while(1){
x--; x--;
x++; x++;
if(x!=10) if(x!=10)
printf("x=%d",x); printf("x=%d",x);
} }
} }
parbegin P1(); P2();
parend
函数偶尔会输出 x=8
,这看起来不可能。
是否与 x--
和 x++
操作实际上被翻译的事实有关机器代码中的 3 条指令(参见符号汇编解码)?
LD R0, X // LOAD into R0 the value of x
INCR R0 (or DECR R0) // { INCR | DECR }-increase/decrease the value of R0 by 1
STO R0, X // STORE the new value back to x
如果是,
那么指令的顺序是什么,以便生成输出 "x=8"
?
如果没有,
那为什么它偶尔会打印x=8
?
最佳答案
完全有可能,而且正是由于你怀疑的原因,而不是完全按照你怀疑的顺序。
x--
语句不是原子的,它由加载操作、减量操作和存储操作组成。因此,如果 x--
被另一个线程抢占,结果可能就像 x--
语句根本没有执行一样。但这不会产生 8
,它实际上会导致 x
达不到 8
这样低的值。
但是,同样适用于 x++
语句:抢占可能导致 x++
永远不会发生,所以在这种情况下的结果将是 x
将无法超过 9
,因此只需一次成功的 x--
即可将其降至 8
.
所以,如果取消的x++
多于x--
,那么x
完全有可能变成8。实际上,在您的代码示例中,x
完全有可能收到您能想到的任何值。
关于assembly - 这两个并行执行的函数怎么可能输出不太可能的结果呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60355962/