为什么跨线程更改共享变量的代码显然不会受到竞争条件的影响?

新手上路,请多包涵

我正在使用 Cygwin GCC 并运行以下代码:

 #include <iostream>
#include <thread>
#include <vector>
using namespace std;

unsigned u = 0;

void foo()
{
    u++;
}

int main()
{
    vector<thread> threads;
    for(int i = 0; i < 1000; i++) {
        threads.push_back (thread (foo));
    }
    for (auto& t : threads) t.join();

    cout << u << endl;
    return 0;
}

使用以下行编译: g++ -Wall -fexceptions -g -std=c++14 -c main.cpp -o main.o

它打印 1000,这是正确的。但是,由于线程覆盖了先前增加的值,我预计数量会更少。为什么这段代码不受相互访问的影响?

我的测试机有4个核心,我对我所知道的程序没有任何限制。

当用更复杂的东西替换共享 foo 的内容时,问题仍然存在,例如

if (u % 3 == 0) {
    u += 4;
} else {
    u -= 1;
}

原文由 mafu 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 209
1 个回答

foo() 太短了,以至于每个线程可能在下一个线程产生之前就完成了。如果您在 --- 在 u++ foo() 之前添加随机时间的睡眠,您可能会开始看到您所期望的。

原文由 Rob K 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏