我的问题是,在阅读线程时,发现如果多个踏板访问一个变量,就会发生竞争条件。我的直觉是,在这种情况下,我的代码会像这样为"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
,或将其与互斥锁同步。
这是不幸的未定义行为的完美示例。
它只是愚弄你期望的结果,你永远不知道它会在何时何地打到你的脸上。
为了防止它,你必须使用原子学或使用互斥锁
您可以添加调试消息以打印增量函数的线程编号和值。 如果增量按线程数排序,则没有争用条件。
还有一点:在竞争条件下你期望什么,这一块只是增加了内存位置的值。它不是一个会导致死锁条件的数据库