Boost:threadライブラリを使用して、シングルスレッドプログラムをマルチスレッドに変更しています。プログラムはunordered_mapをルックアップのhasp_mapとして使用します。私の質問は….
一度に多くのスレッドが書き込みを行い、別の多くのスレッドが読み取りを行いますが、読み取りと書き込みの両方を同時に行うことはできません。つまり、すべてのスレッドが読み取りを行うか、すべてのスレッドが書き込みを行います。それはスレッドセーフであり、コンテナはこれのために設計されていますか?そして、そうなるとしたら、それは本当に並行してパフォーマンスを向上させるでしょうか?何らかのロックメカニズムを使用する必要がありますか?
C++標準では動作が未定義になると言われていますが、それだけですか?
更新:インテルのconcurrent_hash_mapについても考えていました。それは良い選択肢でしょうか?
STLコンテナは、次のことができることが保証されるように設計されています。
A.複数のスレッドが同時に読み取る
または
B. 1つのスレッドが同時に書き込み
複数のスレッドで書き込むことは、上記の条件の1つではなく、許可されていません。したがって、複数のスレッドを書き込むと、未定義の動作であるデータ競合が発生します。
ミューテックスを使用してこれを修正できます。 shared_mutex(shared_locksと組み合わせて)は、そのタイプのmutexが複数の同時リーダーを許可するため、特に役立ちます。
http://eel.is/c++draft/res.on.data.races# は、さまざまなスレッドでconst関数を同時に使用できることを保証する標準の一部です。 http://eel.is/c++draft/container.requirements.dataraces は、異なるスレッドで安全ないくつかの追加の非const操作を指定します。
それはスレッドセーフであり、コンテナはこれのために設計されていますか?
いいえ、標準のコンテナはスレッドセーフではありません。
何らかのロックメカニズムを使用する必要がありますか?
そうです。ブーストを使用しているので、boost::mutex
は良い考えです。 C++ 11にはstd::mutex
。
C++標準では動作が未定義になると言われていますが、それだけですか?
実際、動作は未定義です。未定義の動作は可能な限り最悪の動作であり、それを示すプログラムは定義上正しくないため、「それだけですか?」という意味がわかりません。特に、誤ったスレッド同期は、多くの場合、診断が非常に困難な方法で、ランダムなクラッシュやデータ破損を引き起こす可能性が高いため、絶対に回避することをお勧めします。
更新:インテルのconcurrent_hash_mapについても考えていました。それは良い選択肢でしょうか?
良さそうですが、自分で使ったことがないので意見を述べることはできません。
std :: unordered_mapはコンテナの要件を満たしています(ref http://en.cppreference.com/w/cpp/container/unordered_map )。コンテナーのスレッドセーフについては、次を参照してください http://en.cppreference.com/w/cpp/container#Thread_safety 。
重要なポイント:
既存の回答は主なポイントをカバーしています:
また、次の点にも注意してください。
以前に取得したイテレーター、またはマップ内のアイテムへの参照またはポインターを使用すると、読み取りまたは書き込み操作としてカウントされます
他のスレッドで実行された書き込み操作は、同じスレッドで実行された場合と同じように、ポインター/参照/イテレーターをマップに無効化する可能性があります。
Unordered_mapにアクセスするときは、concurrent_hash_mapを使用するか、mutexを使用できます。 intel concurrent_hash_mapの使用に関する問題の1つは、TBBを含める必要があることですが、すでにboost.threadを使用しています。これら2つのコンポーネントは機能が重複しているため、コードベースが複雑になります。
std::unordered_map
は、一部のマルチスレッド状況に適しています。
Intel TBBの他の同時マップ もあります。
tbb:concurrent_hash_map
。それは挿入/更新のためのきめ細かい、キーごとのロックをサポートします。これは他のいくつかのハッシュマップが提供できるものです。ただし、構文は少し複雑です。 完全なサンプルコード を参照してください。オススメです。tbb:concurrent_unordered_map
。これは基本的に同じもので、キーと値のマップです。ただし、それははるかに低いレベルであり、使用するのはより困難です。ハッシャー、等値演算子、アロケーターを指定する必要があります。公式のIntelドキュメントにも、サンプルコードはありません。推奨されません。