首页 > 解决方案 > 以下代码在并发情况下的可能结果是什么?

问题描述

我看到一个面试问题如下:以下代码结果的可能范围是多少:

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现在2)。在c1被写入变量sum之前t1t2抢占cpu。
  5. 线程t2获取cpu,并增加(1倍)[现在sum将是x(值无所谓)],然后thread t2完成。
  6. 线程t1获取cpu,并将缓存结果写入c1sum,现在sum2.

    我对吗?

标签: c++multithreading

解决方案


此代码会导致未定义的行为,因为sum是从两个不同的线程修改的,没有任何并发​​保护。这在 C++ 标准中称为数据竞争。

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

链接到有关内存模型的 cppreference 页面


推荐阅读