带线程的operator ++(前缀)

时间:2016-06-01 12:32:08

标签: c++ multithreading operators

在朋友之间投注。 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;

}

4 个答案:

答案 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。可能发生之间的任何事情。