2016-08-25 9 views
1

私は読み書きするstd :: map(またはstd :: unordered_map、同様に動作すると仮定しているので)を持っています。私はまた、関連するミューテックスを持っています。std :: map/std :: unordered_mapの安全性を読む

私は地図に読み書きする(要素を挿入または削除する)ことになります。私は、STLコンテナが読み取り安全であると聞きました。もしそうなら、書き込み操作にmutexだけを使うのは安全でしょうか?

マップの値を一度に繰り返し処理する必要があるので、私は質問しています。要素を変更する必要がある場合は、ミューテックスのみを使用したいと思います。

答えて

1

書き込み操作にmutexを使用するだけで安全ですか?

書き込み中にマップから読み取ろうとしないようにする必要があります。したがって、読み込みのみが行われている間にmutexをロックする必要はありませんが、スレッドが書き込み可能な場合、すべてのスレッド(読者も)はmutexを使用する必要があります。

0

一般に、リーダーとライターの両方がミューテックスを取得する必要があります。

そうしないと、データの競合が発生し、同時に読み書きが行われ、結果として未定義の動作が発生する可能性があります。実際には、クラッシュを引き起こす缶や、読者がマップに入れなかったデータが破損する可能性があります。たとえ動作しているように見えても、競合検出器(例えば、thread sanitizerHelgrind)のような有用なツールを混乱させる。また、コードを潜在的に移植性のないものにします。

マップにライターがもう存在しないことを証明でき、変更が他のすべてのスレッドに表示される場合のみ、すべてのアクセスがリーダーになっているため状況が変わっています。この時点では、データレースはありません。同期を取らずに地図から読み取ることは安全です。

更新の可能性がまだある場合は、並列データ構造を使用してロックを回避できます。 C++ 11(およびC++ 17)には提供されていませんが、標準以外の実装が利用可能です。だから、

、あなたが本当にパフォーマンスが必要な場合、あなたはこれらの同時ハッシュマップの実装を見てすることができます(そうでない場合は、単にすべてのアクセスのためのミューテックスと組み合わせてstd::unordered_mapを使用):インテルスレッディング・ビルディングで

  • Concurrent data structuresブロック(TBB)
  • Junction(最速のようですが、マップを使用していないときにスレッドが定期的にクリーンアップ操作を呼び出す必要があります。これは、blog postの「セーフメモリのレクラメーション」で説明しているように、ガベージコレクタを使用せずにメモリを再利用するために行われます。
関連する問題