2个进程P0和P1在竞争条件下同时运行。我想计算执行期间x可能采用的最大值和最小值。x的初始值为0
P0:
for( int i=0; i<1000; i++){
x++;
x-- ;
x++;
}
P1:
for( int j=0; j<2000; j++){
x-- ;
x++;
}
最大值应为4000,最小值应为-2999。但是即使尝试了很多次,我也无法弄清楚。任何形式的帮助将不胜感激!提前致谢。
代码247
理解此问题的关键在于查看每次递增和递减生成的汇编代码。
每个后增量将生成以下代码:
ld [%fp-4], %l0
add %l0, 1, %l0
st %l0, [%fp-4]
每个递减后将生成以下代码:
ld [%fp-4], %l0
sub %l0, 1, %l0
st %l0, [%fp-4]
现在,您正在学习并发性,如果您选择不使用互斥锁和其他并发控制技术,则上述汇编指令实际上可以不确定的方式执行。
现在,这是我们如何获得最大值4000的值。
这是代码将如何执行:
P0:
for( int i=0; i<1000; i++){
x++; //lets call this step 1
x-- ; //step 2
x++; //step 3
}
P1:
for( int j=0; j<2000; j++){
x-- ; //step a (using letters to denote difference in processes)
x++; //step b
}
您的代码将以以下方式执行以实现最大值:
step 1
step a
step b
step 2
step 3
现在,这里的关键是要识别您的读取和写入将变得很脏。这意味着在上面的汇编代码中,加载的值将不会始终反映正确的值。这是如何进行的:
ld [%fp-4], %l0 //read current value of 'x' for step 1
add %l0, 1, %l0 //performs increments
st %l0, [%fp-4] //stores value from step 1
ld [%fp-4], %l0 //begins read for step a
sub %l0, 1, %l0 //performs decrement
ld [%fp-4], %l0 //performs a DIRTY-READ for step b (notice step a hasn't finished executing)
add %l0, 1, %l0 //performs increment
st %l0, [%fp-4] //stores value from increment (value from decrement is now outdated and lost) (this is a dirty write)
st %l0, [%fp-4] //stores value from decrement (this value is actually lost)(this is a dirty write)
从上面的执行中,您可以看到程序集将交织在一起,并且如果没有适当地使用并发,您将不会在堆栈上持久存储正确的'x'值。这样您将获得4000,因为在程序集的某些排列中,您将连续地连续处理4个增量运算符,而递减运算符的结果将无法正确保存。以同样的方式,您将通过依次执行减量运算符而没有正确地将x的值持久保留在增量运算符之后来获得-2999的值。
请让我知道,如果你有任何问题!
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句