我创建了一个线程池,它同时写入同一个向量。
这个实现线程安全吗?
如果不是,我该如何解决?
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
。
答案 0 :(得分:2)
假设您的全局向量未被代码的任何其他部分修改,那么您的代码是线程安全的。
每个线程都要写入(访问)到向量的不同单元格中,因此没有&#34;脏更新&#34; 问题。
此外,矢量的类型是双重的,在现代建筑中大于WORD大小。因此每个阵列单元都不会重叠。
答案 1 :(得分:2)
[container.requirements.dataraces]/1-2:
1为了避免数据争用([res.on.data.races]), 实现应将以下函数视为
const
:begin
,end
,rbegin
,rend
,front
,back
,data
,[...],{{ 1}}和,除了关联或无序 关联容器,at
。2尽管如此([res.on.data.races]),仍需要实现 当包含对象的内容时,避免数据争用 除了
operator[]
之外,同一容器中的不同元素是 同时修改。
答案 2 :(得分:-1)
通常,std::vector
不是线程安全的,但上面的代码将起作用,因为支持数组已预先分配了assign()
方法。
只要编写器不会导致重新分配后备阵列,代码就可以工作。 assign()
方法将预先分配足够的空间,以便在线程写入时不会发生。