我看到了如下采访问题: 以下代码的结果可能在什么范围内:
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 。
t1
获取CPU,并将初始的sum=0
加载到缓存中(假设缓存的总和为c1
,其值现在为0
)。t2
获得CPU,并增加(49倍),现在总和为49。t1
得到CPU,并计算sum = c1 + 1
,现在sum
是1
。t2
获取CPU,并加载sum
(=1
)并计算sum + 1
并缓存结果(c1
为{{1} }现在)。在2
将c1
写入变量sum
之前,t1
抢占了CPU。t2
得到CPU,并增加(1倍)[现在t2
将是sum
(该值无关紧要)],然后是{{1} }。线程x
获取CPU,并写入缓存的结果thread t2
求和,
现在t1
是c1
。
我可以吗?
答案 0 :(得分:1)
此代码导致undefined behaviour,因为sum
是从两个不同的线程修改而来的,没有任何并发保护。在C ++标准中,这称为数据竞赛。
因此,任何行为都是可能的(包括但不限于您提到的所有情况)。