为什么此代码不创建争用条件?



我的问题是,在阅读线程时,发现如果多个踏板访问一个变量,就会发生竞争条件。我的直觉是,在这种情况下,我的代码会像这样为"int a"创建一个竞争条件 https://en.wikipedia.org/wiki/Race_condition#Example 但它不会发生。我的问题是为什么会这样?

我尝试在数组中单独创建多个线程,但没有发生竞争条件。

void increment(int& a) {
++a;
}
int main()
{
int a = 0;
std::thread pool[100];
for (auto& t : pool) {
t = std::thread(increment, std::ref(a));
}

for (auto& t : pool) {
t.join();
}
printf("%d", a);
}

我希望只有一些线程实际上增加了"a"并且发生了竞争条件,但我的代码并非如此

确实

如此。

你只是还没有看到它的任何症状,纯粹是偶然的。

(我希望一次创建和存储一个线程比增量本身慢得多,因此当您进入下一个线程时,通常已经完成了最后一个线程的增量。但你不能保证这一点,这是一个经典的竞争条件。

您应该/必须以原子方式递增a,或将其与互斥锁同步。

这是不幸的未定义行为的完美示例。

它只是愚弄你期望的结果,你永远不知道它会在何时何地打到你的脸上。

为了防止它,你必须使用原子学或使用互斥锁

您可以添加调试消息以打印增量函数的线程编号和值。 如果增量按线程数排序,则没有争用条件。

还有一点:在竞争条件下你期望什么,这一块只是增加了内存位置的值。它不是一个会导致死锁条件的数据库

最新更新