对 std::vector 元素的赋值是线程安全的吗?

Is assignment to a std::vector element thread-safe?

我做了一个同时写入同一个向量的线程池。

这个实现线程安全吗?

如果不是,我该如何解决?

std::vector<double> global_var;

void func1(int i)
{
    global_var[i]=some_computation(i /* only depends on i */);
}

void load_distribution()
{
    const int N_max=100;
    global_var.assign(N_max,0.0);
    std::vector<std::thread> th_pool;
    for(long i=0;i<N_max;i++)
        th_pool.push_back(std::thread(func1,i));

    for(std::thread& tp : th_pool)
        tp.join();
}

更新

global_var 在所有线程终止之前不会被程序的任何其他部分触及。

一般来说,std::vector 不是线程安全的,但是上面的代码可以工作,因为后备数组是用 assign() 方法预分配的。

只要编写者不导致重新分配后备数组,代码就可以工作。 assign() 方法将预分配足够的 space,因此当线程写入它时不会发生这种情况。

假设您的 global 向量未被代码的任何其他部分修改,那么您的代码是线程安全的。

每个线程都将写入(访问)向量的不同单元格,因此不存在"dirty update"问题。

此外,向量的类型是双精度型,在现代体系结构中大于 WORD 大小。所以每个阵列单元之间不重叠。

[container.requirements.dataraces]/1-2:

1 For purposes of avoiding data races ([res.on.data.races]), implementations shall consider the following functions to be const: begin, end, rbegin, rend, front, back, data, [...], at and, except in associative or unordered associative containers, operator[].

2 Notwithstanding ([res.on.data.races]), implementations are required to avoid data races when the contents of the contained object in different elements in the same container, excepting vector<bool>, are modified concurrently.