2017-09-22 9 views
4

このタイプの操作は安全であると考えられますか? (言い換えれば、ビットセットが別のスレッドで変更されている場合、偽の中間値を読み取る機会はありません)?具体的には、読み込みが安全かどうかだけに興味があります。言い換えれば、2つの別々のスレッドからビットセットに書き込むことが安全かどうかは問いません。別のスレッドによって変更されるビットセット(C++)からビットをアクセス(読み込み)することは安全ですか

例:スレッド1は、bsの他のビットが同時にセット/クリアされているかどうかにかかわらず、確実にビット5の現在の状態を取得しますか?

std::bitset<64> bs; 

//thread 1: 
bool val; 
val=bs.test(5); 
// ... 

//thread 2: 
// set/clear a few bits 
bs.set(1); 
bs.set(3); 
bs.set(5); 
bs.reset(6); 
// ... 
+3

スタンダードライブラリコンテナは、並行読み込みと書き込みの際にスレッドセーフではありません。 –

+0

あなたは半分読むことができると思いますか?そのようなことはありません。スレッドAがビットを読み取ってスレッドBをセットするのを待っている場合、それは問題ありません。大きな画像が問題になることがあります。 – lakeweb

+0

@ lakeweb私の懸念は半分ではなく、スレッドBが* different *ビットを設定していると、ビットスレッドAが一時的に異なる状態になる可能性があります。 –

答えて

1

このようにstd::bitsetを使用すると、でなく、スレッドセーフです。

これは標準のビットセット(20.9.2.2-51を§)アクセスについて言うことである:潜在的に、データ競合の存在を決定するために得られた参照を介して任意のアクセスまたは更新を

を基本となるビットセット全体にアクセスまたは変更する。

したがって、別の実行スレッドでビットセットオブジェクトを読み込みながらビットセットオブジェクトに書き込むことは、データ競合(未定義の動作を引き起こす)です。すべてのスレッドが異なるインデックスを使用してbitsetオブジェクトにアクセスしても

0

STLコンテナはスレッドセーフではありません。中間値は得られませんが、スレッドが同期していない場合は、値のセットが無視されることがあります。 atomic操作を使用してください。

+1

標準コンテナは、直接アクセスできない場合は要素が変更されないという意味でスレッドセーフです。すなわち、 'std :: vector vec {1、2、3}; std :: thread {[&]()mutable {vec [0] ++; }}。detach();}}。 vec [1] ++; 'is legal –

+0

@PasserByこれが' std :: bitset <64> 'に当てはまるかどうかは疑問です。私のプラットフォームでは、サイズは8で、8つの異なるアドレスが可能です。おそらくあなたは64ビットを同時に変更することはできません.64スレッドと言いましょう – LWimsey

+0

@LWimsey面白いことに、ビットセットは標準のコンテナとはみなされません。 –

1

ビットセットはアトミックな変更を提供しないため、ビットの変更により、近くのビットの古い値がラッチされることがあります。

reset(5)があった場合、スレッド1は設定されたビットを決して見ることができない可能性があります。

関連する問題