私はstd::map< StudentName, Marks >
どこにStudentName
いstd::string
てMarks
、整数です。
現在、私のアプリケーションでは、複数のスレッドがこのマップにアクセスして、次のことを行っています。
- 検索します
StudentName
。存在する場合は、その を増やしますMarks
。 Marks
の減少StudentName
。- マップに追加
StudentName
します。 - マップから削除
StudentName
します。
質問:std::map
マルチスレッド環境で上記の操作を行う最も効率的な方法は何ですか?
現在の解決策:
マップ上でこれらすべての操作を行うコードは、クリティカル セクション内に配置されます。しかし、これはパフォーマンスを低下させます。
(たとえば、あるスレッドが特定の生徒に点数を追加している場合、別の生徒に点数を追加したい他のスレッドが待機する必要があるのはなぜですか?)
これが私ができると思うことです:
SO に関する他の同様の質問/回答からマップ上のマルチスレッドに関する情報を収集しました。提供std::map
されているのはスレッド セーフではありません (つまり、マップが更新されているときに他のスレッドがマップにアクセスしてはなりません)。
- 最後の 2 つの (生徒名の追加/削除) アクティビティのみを排他的に配置したい (マップへの要素の追加/マップからの要素の削除中に、他のアクティビティを並行して実行しないでください)
- 複数のスレッドがマップの同じ要素にアクセスすることを許可しないでください (複数のスレッドが同じ生徒の点数を同時に増減させないようにするため)
しかし、どうすればこれを達成できるかわかりません (どのスレッド同期オブジェクト/テクノロジを使用できるか) VS2010 を介して Windows でこのアプリケーションを開発しています
ここで提案や代替アプローチをお願いします。
更新: 皆様のご意見をお寄せいただきありがとうございます。残念ながら、VS2010 で使用できるアトミック int はありません。というわけで、いただいた情報をもとにこれからやっていきたいと思います。3 種類のロックを用意します: マップ上: map_read_lock、map_write_lock 要素上: element_write_lock (要素ごと)
今、
マップ内の要素を見つけるとき: get map_read_lock (これにより、同時検索が可能になります)
マップに要素を追加/削除する場合: get map_write_lock (これにより、コンテナーの同時更新が防止されますが、これはお勧めできません)
値を変更する場合: Get (map_read_lock & element_write_lock) (これにより、異なる値への並列変更が可能になりますが、同じ値への同時変更が防止されます。また、コンテナが更新されているときに値が変更されることも、その逆も防止されます)