【发布时间】:2019-09-04 18:07:40
【问题描述】:
我发现了一个我能够在 linux 中的g++ 下重现的竞争条件示例。我不明白这个例子中操作顺序的重要性。
int va = 0;
void fa() {
for (int i = 0; i < 10000; ++i)
++va;
}
void fb() {
for (int i = 0; i < 10000; ++i)
--va;
}
int main() {
std::thread a(fa);
std::thread b(fb);
a.join();
b.join();
std::cout << va;
}
如果我使用了va = va + 1;,我可以理解订单很重要,因为在返回分配给 LHS va 之前,RHS va 可能已经改变。有人可以澄清一下吗?
【问题讨论】:
-
不确定需要澄清什么。你自己说这是一场比赛。种族引入了未定义的行为。任何事情都有可能发生。
-
两个线程都试图同时修改
va,即使在for循环中也是如此。谁赢?未知,所以va的最终值可以是任何值。 -
我怀疑你认为递增和递减操作是原子的。他们不是。
-
即使操作是原子操作,如果没有同步,也无法保证对
va的更改是否或何时实际推送到其他线程可以看到的位置。例如,va可以很好地存储在寄存器中。 -
顺便说一句,优化器可以将这些方法更改为
va += 10000;、va += 10000;,从而减少更多“机会”看到比赛效果。
标签: c++ concurrency race-condition