どの操作がスレッドセーフにstd::地図か?
-
24-09-2019 - |
質問
かい:
stl::map<std::string, Foo> myMap;
は以下の関数のスレッド安全ですか?
myMap["xyz"] ?
I.。たいていのこの巨大な読み取り専用mapにするのではなく、多くのスレッドがわからない場合でも検索では、スレッドで安全です。
すべてが書き込まれます。
研修の最後二日間、複数のスレッドからの読み込みます。
私の手続きを避けるためのロックを作ることfaastとが可能です。(yaya可能な早期に最適化さん)
解決
理論的には何のSTLコンテナはスレッドセーフではありません。コンテナが同時に変更されていない場合は実際には読書が安全です。すなわち標準は、スレッドについての仕様を行いません。標準の意志とIIUCの次のバージョンでは、それは、安全な読み取り専用の動作が保証されます。
あなたが本当に懸念している場合は、バイナリ検索とソートされた配列を使用します。
他のヒント
C ++ 11は、すべてのメンバ関数がconst
として宣言されている必要があり、複数の読者のために、スレッドセーフである。
myMap["xyz"]
がstd::map::operator[]
として宣言されていないとして、 const
を呼び出すと、スレッドセーフではありません。
myMap.at("xyz")
がstd::map::at
として宣言されているようconst
を呼び出すと、スレッドセーフしかしである。
少なくともマイクロソフトマイクロソフトの実装では、読書からの容器はスレッドセー(参考).
しかし、 std::map::operator[]
の変更ができるデータを宣言されていません const
.するようにしましょう利用 std::map::find
, である const
, してもらいましょう const_iterator
は、逆参照です。
理論的には、読み取り専用のデータ構造と関数にはスレッドセーフのためのロックは必要ありません。本質的にスレッドセーフです。がある データ競合はありません 同時メモリ読み取りについて。ただし、単一スレッドのみによる安全な初期化を保証する必要があります。
マックス・Sとして指摘された、主に次のようなマップ内の要素を読み取る実装 myMap["xyz"]
書き込み操作は行われません。そうであれば、安全です。ただし、繰り返しになりますが、初期化フェーズを除いて構造を変更するスレッドがないことを保証する必要があります。
STLコレクションはスレッドセーフではありませんが、それは1つに、スレッドの安全性を追加するために、かなり簡単です。
あなたの最善の策は、問題のコレクションの周りにスレッドセーフラッパーを作成されます。