并行写入相同的值

Mor*_*enn 4 c++ multithreading memory-model race-condition c++11

我有一个程序会产生多个线程,这些线程可能会将完全相同的值写入完全相同的内存位置:

std::vector<int> vec(32, 1); // Initialize vec with 32 times 1
std::vector<std::thread> threads;

for (int i = 0 ; i < 8 ; ++i) {
    threads.emplace_back([&vec]() {
        for (std::size_t j = 0 ; j < vec.size() ; ++j) {
            vec[j] = 0;
        }
    });
}

for (auto& thrd: threads) {
    thrd.join();
}
Run Code Online (Sandbox Code Playgroud)

在此简化的代码中,所有线程都可以尝试将完全相同的值写入中的相同内存位置vec。这是一场数据竞赛可能会触发未定义的行为,还是安全的,因为在再次连接所有线程之前从不读取值?

如果存在潜在的危险数据竞争,那么使用std::vector<std::atomic<int>>std::memory_order_relaxed存储的替代方法足以防止数据竞争吗?

dyp*_*dyp 5

语言律师答案,[多线程简介] n3485

21如果一个程序的执行在不同线程中包含两个冲突的动作,其中至少一个不是原子的,且两个动作均未发生在另一个线程上,则它的执行将引起数据争用。任何此类数据争用都会导致未定义的行为。

4如果两个表达式求值之一修改一个内存位置,而另一个表达式访问或修改同一内存位置,则这两个表达式求值会发生冲突


会使用std::vector<std::atomic<int>>,而不是与std::memory_order_relaxed商店,而不是足以防止数据争?

是。这些访问是原子的,并且通过线程的连接引入了事前关系。从线程中产生这些工作程序(通过进行同步.join)的任何后续读取都是安全且已定义的。