在朋友之间投注。 sum变量定义为全局变量。 我们有2个线程在循环1..100上运行,并且每个循环将sum加1。
会打印什么? "总和="
int sum = 0;
void func(){
for (int i=0 ; i<= 100; i++){
sum++;
}
}
int main(){
t1 = Thread(func);
t2 = Thread(func);
t1.start();
t2.start();
t1.join();
t2.join();
cout << "sum = " << sum;
return 0;
}
答案 0 :(得分:8)
这是未定义的行为所以我要说42.当你有多个线程访问共享变量并且至少它们是一个编写器时,你需要同步。如果你没有那个同步,那么你有未定义的行为,我们无法告诉你会发生什么。
您可以使用std::mutex
,也可以使用std::atomic
来获取同步并定义程序行为。
答案 1 :(得分:6)
总和没有单一价值。如果有0个竞争条件,则该值将为200.如果循环的每次迭代都存在竞争条件(不太可能),则可能低至100.或者它可能介于两者之间。
你可能认为sum ++是一个原子操作,但它实际上是sum = sum + 1的语法糖。在这个操作中有可能存在竞争条件,所以每次运行它时总和可能不同。 / p>
想象一下sum的当前值是10.然后t1进入循环并读取sum(10)的值,然后停止让t2开始运行。然后t2将读取与t1相同的和(10)值。然后,当每个线程递增时,它们都会将其递增为11.如果没有其他竞争条件,则sum的结束值将为199。
这是一个更糟糕的情况。想象一下,sum的当前值再次为10。 t1进入循环并读取sum(10)的值,然后停止让t2开始运行。 t2再次读取sum(10)的值然后自己停止。现在t1再次开始运行,它循环10次,将sum的值设置为20.现在t2再次启动并将sum增加到11,所以你实际上减去了sum的值。
答案 2 :(得分:1)
由于增量不是atomic,因此会产生undefined behaviour。
答案 3 :(得分:0)
它将是100到200之间的随机值。两个线程之间存在竞争条件,没有相互排斥。因此,一些++操作将丢失。这就是为什么当一个线程的所有++操作都丢失时你将获得100,而当没有任何东西丢失时你将获得200。可能发生之间的任何事情。