web-dev-qa-db-ja.com

shared_mutexをブーストするC ++ 11と同等

boost::shared_mutexに相当するC++ 11がありますか。または、C++ 11で複数リーダー/単一ライターの状況を処理する別のソリューションですか?

54
Haatschii

試してみましたが、shared_mutexをC++ 11に。将来の標準として提案されています。提案は here です。

Edit:改訂版(N3659) 受け入れられました C++ 14用。

実装は次のとおりです。

http://howardhinnant.github.io/shared_mutex

http://howardhinnant.github.io/shared_mutex.cpp

69
Howard Hinnant

シンプル...ありません。 readers-writer ロックの標準C++実装はありません。

ただし、ここにはいくつかのオプションがあります。

  1. あなたはあなた自身のリーダライタロックを作るためにあなた自身のデバイスに残されています。
  2. Win32'sPOSIX's 、または Boost's などのプラットフォーム固有の実装を使用してください。
  3. まったく使用しないでください。C++ 11にすでに存在する mutex を使用してください。

#1を使用して独自の実装を行うのは恐ろしい作業であり、正しくない場合はコードを競合状態で埋めることができます。 reference implemenation があり、これによりジョブが少し簡単になります。

プラットフォームに依存しないコードが必要な場合、またはリーダー/ライターロックのような単純なもののためにコードに追加のライブラリを含めたくない場合は、#2をウィンドウから外すことができます。 。

また、#3には、ほとんどの人が気付かないいくつかの注意事項があります。リーダー/ライターロックの使用は、パフォーマンスが低いことが多く、コードよりも理解しにくいコードがあります。単純なミューテックスを使用した同等の実装。これは、リーダーライターのロック実装の裏で行わなければならない余分なブックキーピングのためです。


私はあなたにあなたの選択肢だけを提示することができます、実際にはそれぞれの費用と利益を比較検討し、最も効果的なものを選ぶのはあなた次第です。


編集:C++ 17には shared_mutex タイプがあり、複数の同時リーダーを使用する利点がある状況に対応shared_mutex自体のパフォーマンスコストを上回る。

18
Sean Cline

いいえ、C++ 11にはboost::shared_mutexに相当するものはありません。

ただし、読み取り/書き込みロックはC++ 14以降でサポートされています。

違いは、std::shared_timed_mutexが追加のタイミング操作を追加することです。 SharedTimedMutex concept を実装します。これは、より単純な TimedMutex concept の拡張であり、std::shared_mutexによって実装されます。


読み取り/書き込みミューテックスのロックの取得は、通常の std::mutex の取得よりもコストがかかることに注意してください。その結果、読み取り/書き込みミューテックスは、頻繁ではあるが短い読み取り操作がある場合、パフォーマンスを改善しません。読み取り操作が頻繁で費用がかかるシナリオに適しています。 Anthony Williamsの投稿 から引用するには:

Shared_mutexをロックするコストは、リーダースレッドであっても、プレーンなstd :: mutexをロックするコストよりも高くなります。これは機能の必要な部分です--- mutexよりshared_mutexの可能な状態があり、コードはそれらを正しく処理する必要があります。このコストは、オブジェクトのサイズ(実装とPOSIX実装の両方にプレーンミューテックスと条件変数の両方が含まれる)と、ロックおよびロック解除操作のパフォーマンスの両方で発生します。

また、shared_mutexは競合のポイントであるため、スケーラブルではありません。 shared_mutexをロックすると、読み取りロックの場合でも、mutexの状態が必ず変更されます。したがって、shared_mutex状態を保持しているキャッシュラインは、ロックまたはロック解除操作を実行しているプロセッサに転送する必要があります。

頻繁に短い読み取り操作を実行するスレッドが多数ある場合、マルチプロセッサシステムでは、これにより多くのキャッシュピンポンが発生し、システムのパフォーマンスに大きな影響を与える可能性があります。この場合、リーダーは基本的にシリアル化されるため、プレーンミューテックスを使用するだけの単純な設計を採用することもできます。

読み取りが頻繁に行われない場合、競合は発生しないため、同時読み取りを心配する必要はありません。とにかく、このシナリオにはプレーンなミューテックスで十分です。

読み取り操作に時間がかかる場合、この競合の結果は、読み取りロックを保持している間に費やされる時間によってd小化されるため、目立たなくなります。ただし、ロックを保持しながら時間のかかる操作を実行することは、設計上の悪臭です。

ほとんどの場合、shared_mutexに代わるより良い選択肢があると思います。これらは、コンテキストに応じて、プレーンミューテックス、shared_ptrのアトミックサポート、慎重に構築された同時コンテナの使用、または他の何かである可能性があります。

6
Philipp Claßen