boost:threads の代わりに新しい標準スレッドを使用したいのですが、古い shared_mutex が利用できないことに気付きました。この機能を置き換えて、複数のリーダーと単一のライターのロックを提供するための適切な推奨事項は何ですか?
2 に答える
std::shared_mutex
C++14 標準ライブラリの一部になります。提案を策定して徹底的に議論する時間がなかったという理由だけで、C++11 にはなりませんでした。
それでも使えboost::shared_mutex
ます。Windows では、Windows Vista 以降で作業している場合、速度とメモリ消費が最適化されたSlim Read-Write Locks を使用できます。
スタック オーバーフローの質問「C++11 は、boost shared_mutex と同等」、特に次のリンクされた電子メールの会話を確認する必要があります: http://permalink.gmane.org/gmane.comp.lib.boost.devel/ 211180 (これは、shared_mutex の承認に対する C++11 委員会の抵抗を説明しています)。また、Joe Duffy のウェブログでの次の実験: http://www.bluebytesoftware.com/blog/2009/02/12/ReaderwriterLocksAndTheirLackOfApplicabilityToFinegrainedSynchronization.aspx。
リーダー/ライター ロックを検討するたびに、次の 6 つの質問を自問してください。それらのいずれにも「いいえ」と答えることができる場合、リーダー/ライターロックはプログラムを悪化させますが、良くはしません。
- 私の共有オブジェクトは
const
?shared_mutex
私は人生で の正しい使い方よりも間違った使い方を見てきました。shared_mutex
を正しく使用するには、リーダー クリティカル セクション内で共有オブジェクトを宣言しても、コンパイラに問題が生じないようにする必要があります。const
「消費者」は、「データ構造をまったく変更しない人」と同等ではありません。 - クリティカル セクションは本当に長いですか? shared_mutex をロックすると、通常のミューテックスをロックするよりもはるかにコストがかかります。ロックの取得/解放のオーバーヘッドの増加を補うために、重要なセクションで多くの作業を行う必要があります。
- クリティカル セクションはそれほど長くする必要がありますか? 重要なセクションですべての作業を行う必要があるかどうかを自問する必要があります。多くの場合、一連の準備作業や
const
、共有オブジェクトへの呼び出しを囲む戻りオブジェクトをマッサージする作業があります。共有オブジェクトの最初の使用から共有オブジェクトの最後の使用までのデータ依存パス上にない余分な作業の多くは、クリティカル セクションの外に移動できます。 - ロックの競合は本当にパフォーマンスの問題ですか? クリティカル セクションが長い場合でも、ロックの競合が実際にパフォーマンスの問題であることを完全に確認する必要があります。重大なロック競合が発生していない場合は、リーダー/ライター ロックに切り替えても何も得られません。
- 粒度の細かいロック スキームに切り替えることで、ロックの競合を減らすことはできますか? 単一のロックを使用して複数のオブジェクトを保護していますか? 各オブジェクトに独自のロックを与えることができますか?
- 読み手と書き手の比率は1:1を大幅に上回っていますか? クリティカル セクションが長く、ロックの競合が深刻な問題である場合でも、リーダー/ライター ロックのメリットを得るには、ライターに対するリーダーの比率を非常に高くする必要があります。金額は、ハードウェア上のアトミック命令のコストと、特定の実装の品質によって異なります。(Joe Duffy は、彼のマシンでは、リーダー/ライター ロックを成功させるには、リーダーとライターの比率を 20:1 程度にする必要があることを発見しました。)