在并发情况下,以下代码的可能结果是什么?

时间:2018-11-08 04:17:14

标签: c++ multithreading

我看到了如下采访问题: 以下代码的结果可能在什么范围内:

void ThreadProc(int& sum)
{
    for (int i = 1; i <= 50; i++)
    {
        sum += 1;
    }
}

int main()
{
    int sum = 0;
    thread t1(ThreadProc, std::ref(sum));
    thread t2(ThreadProc, std::ref(sum));
    t1.join();
    t2.join();
    cout << sum << '\n';
    return 0;
}

给出的答案是 [50,100] 。 但是,我认为应该为 [2,100] 。 如果给定以下序列,则sum将为 2

  1. 线程t1获取CPU,并将初始的sum=0加载到缓存中(假设缓存的总和为c1,其值现在为0)。
  2. 线程t2获得CPU,并增加(49倍),现在总和为49。
  3. 线程t1得到CPU,并计算sum = c1 + 1,现在sum1
  4. 线程t2获取CPU,并加载sum=1)并计算sum + 1并缓存结果(c1为{{1} }现在)。在2c1写入变量sum之前,t1抢占了CPU。
  5. 线程t2得到CPU,并增加(1倍)[现在t2将是sum(该值无关紧要)],然后是{{1} }。
  6. 线程x获取CPU,并写入缓存的结果thread t2求和, 现在t1c1

    我可以吗?

1 个答案:

答案 0 :(得分:1)

此代码导致undefined behaviour,因为sum是从两个不同的线程修改而来的,没有任何并发​​保护。在C ++标准中,这称为数据竞赛

因此,任何行为都是可能的(包括但不限于您提到的所有情况)。

Link to cppreference page about memory model