我看到一个面试题如下: 以下代码的结果的可能范围是什么:
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。
- thread
t1
获取cpu,并将初始的sum=0
加载到缓存中(假设缓存的sum是c1
,它的值现在是0
)。 - 线程
t2
获取cpu,增加(49次),现在总和为49。 - 线程
t1
获取cpu,计算sum = c1 + 1
,此时sum
为1
。 - 线程
t2
获取 cpu,并加载sum
(=1
) 并计算sum + 1
并缓存结果(c1
现在是2
)。在c1
被t1
写入变量sum
之前,t2
抢占了cpu。 - thread
t2
获取 cpu,并增加(1 倍)[现在sum
将是x
(值不matter)], 然后thread t2
结束了。 线程
t1
获取cpu,并将缓存结果c1
写入sum, 现在sum
是2
。我说得对吗?
最佳答案
此代码导致 undefined behaviour因为 sum
是从两个不同的线程修改的,没有任何并发保护。这在 C++ 标准中称为数据竞争。
因此任何行为都是可能的(包括但不限于您提到的所有情况)。
关于c++ - 以下代码在并发情况下的可能结果是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53201488/