web-dev-qa-db-ja.com

std :: mapスレッドセーフ

Std :: mapのオブジェクトへの参照はスレッドセーフですか?

std::map< std::string, Object >   _objects;

mapは多くのスレッドから変更でき、このアクセスは同期されますが、1つのインスタンスとスレッドからのみアクセス可能な値(オブジェクト&)への参照です。 Objectを使用した書き込み操作と、別のスレッドがアイテムをマップに追加しても安全ですか?再割り当てしますか?

21
deeptowncitizen

マップ内の要素は安定しており、要素がマップから消去されない限り、移動または無効化されません。 1つのスレッドのみが特定のオブジェクトに書き込みを行っており、マップ自体への変更が正しく同期されている場合、I believeそれは安全です。実際には安全だと確信しており、理論的にも安全だと思います。

標準では、[container.requirements.dataraces]で、異なるスレッドが異なる要素を変更できることを保証しています。

(17.6.5.9)にもかかわらず、vector<bool>を除く同じシーケンスの異なる要素に含まれるオブジェクトのコンテンツが同時に変更される場合、データの競合を回避するために実装が必要です。

これにより、要素の変更のみが可能になり、要素の変更中にマップに新しい要素を挿入することはできません。 std::vectorなどの一部のコンテナでは、ベクトル自体を変更すると、要素の再割り当てと移動によって要素が変更される場合がありますが、[associative.reqmts]/9はstd::mapが既存の要素を無効にしないことを保証します。

std::mapのメンバー関数は、その要素の2番目のメンバー(つまりmapped_type)にアクセスする必要がないため、[res.on.data.races]/5は、他のスレッドは書き込みと競合しないと考えていますマップを変更するときにそのメンバーに。 (パズルの最後のピースをくれたYakkに感謝します)

7
Jonathan Wakely