2016-12-29 81 views
1

私は同じベクトルに同時に書き込むスレッドプールを作っています。std :: vector要素への代入はスレッドセーフですか?

この実装スレッドは安全ですか?

そうでない場合は、どのように修正する必要がありますか?すべてのスレッドが終了する前に

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は、プログラムの他の部分に触れされることはありません。

+1

現在のスニペットは実際にはスレッドセーフです。 ...まだ、あなたのデザインは本当に壊れやすいです。定義されていない動作を導入する 'global_var'を変更する可能性のあるコード部分があるかもしれません。 – WhiZTiM

+0

@WhiZTiM' global_var'は、すべてのスレッドが終了する前にプログラムの他の部分によって変更されないことを保証します。 – ar2015

+0

完全なコード[ここ](http://pastebin.com/S3GYTYBf)の場合にのみ。 – ar2015

答えて

1

グローバルベクトルが他のコード部分によって変更されていないと仮定すると、コードはスレッドセーフです。

各スレッドはベクトルの別のセルに書き込み(アクセス)するため、「ダーティ更新」の問題はありません。

さらに、ベクターのタイプはダブルです。現代建築ではWORDサイズよりも大きいです。したがって、各アレイセルは他のものと重なり合わない。

+0

ありがとうございます。 'vector 'を使うとどうなりますか?何か問題はありますか? – ar2015

+0

@ ar2015メモリがアライメントされた方法で割り当てられていない場合 –

+0

アライメントされたメモリ割り当ての方法またはアライメントされていない方法の例は何ですか? – ar2015

-1

通常、std::vectorはスレッドセーフではありませんが、バッキングアレイにassign()メソッドがあらかじめ割り当てられているため、上記のコードが機能します。

ライターがバッキングアレイを再割り当てしない限り、コードは機能します。 assign()メソッドは十分なスペースをあらかじめ割り当てておくので、スレッドがスレッドに書き込むときには発生しません。

+0

ありがとうございます。しかし、このコードをどのように修正するべきですか? – ar2015

+0

実際には、割り当ては既に使用されています。 'global_var.assign(N_max、0。0); ' – ar2015

+0

'ベクトル 'の代わりに、 'ベクター'を使用して、それ自身の中に他のベクトルを含めるとどうなるでしょうか?この場合、代入はベクトルを無効にしますか? – ar2015

1

[container.requirements.dataraces]/1-2:データの競合を回避する目的で

1([res.on.data.races])は、 実装があると、以下の機能を考慮しなければならないconstbeginendrbeginrendfrontbackdata、[...]、at、および関連性または順序付けされていないもの以外 連想コンテナ、operator[]

2かかわらず([res.on.data.races])、実装がvector<bool>を除いて、ときに、同じ容器内 異なる要素に含まれるオブジェクトのコンテンツデータ競合を回避するために を要求され、同時に変性 あります。

関連する問題