2

私はstd::map< StudentName, Marks >どこにStudentNamestd::stringMarks、整数です。

現在、私のアプリケーションでは、複数のスレッドがこのマップにアクセスして、次のことを行っています。

  1. 検索しますStudentName。存在する場合は、その を増やしますMarks
  2. Marksの減少StudentName
  3. マップに追加StudentNameします。
  4. マップから削除StudentNameします。

質問:std::mapマルチスレッド環境で上記の操作を行う最も効率的な方法は何ですか?

現在の解決策: マップ上でこれらすべての操作を行うコードは、クリティカル セクション内に配置されます。しかし、これはパフォーマンスを低下させます。
(たとえば、あるスレッドが特定の生徒に点数を追加している場合、別の生徒に点数を追加したい他のスレッドが待機する必要があるのはなぜですか?)

これが私ができると思うことです:
SO に関する他の同様の質問/回答からマップ上のマルチスレッドに関する情報を収集しました。提供std::mapされているのはスレッド セーフではありません (つまり、マップが更新されているときに他のスレッドがマップにアクセスしてはなりません)。

  1. 最後の 2 つの (生徒名の追加/削除) アクティビティのみを排他的に配置したい (マップへの要素の追加/マップからの要素の削除中に、他のアクティビティを並行して実行しないでください)
  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) (これにより、異なる値への並列変更が可能になりますが、同じ値への同時変更が防止されます。また、コンテナが更新されているときに値が変更されることも、その逆も防止されます)

4

3 に答える 3

3

あるスレッドが生徒 A の成績を上げ、別のスレッドが生徒 A を削除するとどうなるでしょうか? マークを変更するだけでもマップをロックする必要があります。または、より複雑なトランザクション管理が必要です (これはおそらく、このような単純なケースでは正当化されません)。

または、マップで rwlock を使用し、マップ内の各要素で排他ロックを使用できます。マークを変更するには、マップに対して読み取りロックを取得し、要素に対して排他ロックを取得します。生徒を追加または削除するには、マップで書き込みロックを取得します。しかし、これにはかなりの追加リソースが必要です。

于 2013-08-30T11:00:51.190 に答える
0
  • 最初の質問: 生徒の採点はどの程度効率的であるべきですか?
  • 2 番目の質問: マルチスレッドは本当に必要ですか? 効率化のためなら、役に立たないかもしれません。

その後、リーダーロックが排他的ではないリーダー/ライターロックを検討できます。ただし、実際の採点はライティングであるため、競合を避けるために学生ごとに別のロックが必要になる可能性があるため、注意してください。

于 2013-08-30T10:59:23.983 に答える
0
  1. 最後の 2 つの (生徒名の追加/削除) アクティビティのみを排他的に配置したい (マップへの要素の追加/マップからの要素の削除中に、他のアクティビティを並行して実行しないでください)

このためには、マップのリーダー/ライター ロックが必要です。

  • 追加/削除には排他アクセスが必要です (ライター)
  • 学生へのアクセスには、(のみ) 共有アクセス (リーダー) が必要です
  1. 複数のスレッドがマップの同じ要素にアクセスすることを許可しないでください (複数のスレッドが同じ生徒の点数を同時に増減させないようにするため)

これも比較的単純です。マップの各要素には独自のロックが必要です。このようにして、マップ構造を変更せずに要素にアクセスする場合、次のことができます。

  • 共有アクセスでマップをロックする
  • 個々の要素をロックします (つまり、各要素には独自のロックが必要です)

したがって、複数の個々の要素に並行してアクセスします。

の特定のケースではMark、 を調べることもできますstd::atomicatomicシンプルなものがあなたが望むことをすることができるとき、ロックを使う必要はありません:)

于 2013-08-30T14:38:29.917 に答える