这个并行循环会导致数据竞争吗?

时间:2015-08-25 20:01:26

标签: c++ multithreading thread-safety data-race

我在std::vector的并行循环之前填充了std::pair<Object, bool>。 bool都初始化为true。循环大致如下:

for (int x = 0; x < xMax; ++x) // can parallelising the loop in x cause a data race?
    for (int y = 0; y < yMax; ++y)
        for (auto& i : vector)
            if (i.first.ConstantFunctionDependingOnlyOnInput(x, y))
                i.second = false;

由于我们只是将bool设置为false我没有看到这导致数据竞争,但我不相信我对多线程的直觉。对此bool的结果进行的操作在之后的单个线程中完成(使用标准算法擦除向量中bool == true的所有元素。

这里的建议将不胜感激。我打算使用std::atomics,但当然,它们无法在std::vector中使用,因为它们不是可复制构造的。

干杯!

2 个答案:

答案 0 :(得分:3)

以下是一个可能失败的方法的示例,现实世界的代码已经以这种方式失败。

    for (auto& i : vector)
        if (i.first.ConstantFunctionDependingOnlyOnInput(x, y))
            i.second = false;

编译器可能会按如下方式优化此代码:

for (auto& i : vector);
{
     bool j = i.second;
     bool k = i.first.Function(x, y);
     i.second = k ? false : j;
}

这可能导致一个线程覆盖另一个线程的结果。这可能是合法的优化,因为无条件写入可能比条件写入更便宜,因为它不会被错误预测。

答案 1 :(得分:-2)

你是正确的 - 这将在任何真实世界的系统上完全按照你的预期行事(没有数据竞争)。虽然根据C ++标准正式未定义的行为,但现实世界的系统并不是那样工作的。 Here是对包含此问题的更广泛问题的回答。

这里的标准中的文字说这是正式未定义的,但是:

  

如果其中一个修改内存,则两个表达式评估会发生冲突   位置(1.7)和另一个访问或修改相同的内存   位置。

如果您想要标准保证安全性,可以考虑atomic内存访问。