61

たとえば、c++0xインターフェイス

これらのどれ(cv、mutex、lock)をいつ使用するかを理解するのに苦労しています。誰かがリソースを説明または指摘できますか?

前もって感謝します。

4

3 に答える 3

85

参照しているページでは、「mutex」は実際の低レベルの同期プリミティブです。ミューテックスを取得してから解放することができ、一度に1つのスレッドのみがそれを取得できます(したがって、同期プリミティブです)。再帰的ミューテックスは、同じスレッドで複数回取得できるミューテックスであり、他の人が取得する前に、同じスレッドで何度も解放する必要があります。

ここでの「ロック」は、コンストラクターでミューテックスを受け取り、デストラクタで解放するC++ラッパークラスです。これは、C++スコープの同期を確立するのに役立ちます。

条件変数は、ロックと「シグナリング」メカニズムを組み合わせた、より高度な高レベルの同期プリミティブです。これは、スレッドがリソースが使用可能になるのを待つ必要がある場合に使用されます。スレッドはCVで「待機」でき、リソースプロデューサーは変数を「通知」できます。この場合、CVを待機しているスレッドは通知を受け取り、実行を続行できます。ミューテックスはCVと組み合わされて、スレッドがCVを待機し始めると同時に、別のスレッドがCVに信号を送りたいという競合状態を回避します。その場合、信号が配信されるか失われるかを制御することはできません。

于 2009-06-28T18:28:09.187 に答える
5

私はC++0xについてはあまり詳しくないので、この答えを一粒の塩で取ってください。

re:ミューテックスとロック:投稿したドキュメントから、amutexはOSミューテックスを表すオブジェクトであるように見えますが、aはRAIIパターンlockを容易にするためにミューテックスを保持するオブジェクトです。

条件変数は、ブロッキング/シグナリングメカニズム(シグナル+待機)を相互排除メカニズムに関連付けるための便利なメカニズムですが、システムプログラマーがcondvarとmutexの間の関連付けを選択できるように、OSでそれらを分離したままにします。(同時にアクセスされるオブジェクトの複数のセットを処理するのに便利です)Rob Krtenは、QNXに関する彼の本のオンライン章の1つで、condvarsに関するいくつかの良い説明をしています。

一般的な参考資料として:この本(まだ出ていません)は面白そうです。

于 2009-06-28T18:28:37.737 に答える
3

この質問は回答済みです。これらの同期プリミティブをいつ使用するかを決定するのに役立つ可能性があるこれを追加するだけです。

単純に、ミューテックスは、複数のスレッドのクリティカルセクションにある共有リソースへの相互アクセスを保証するために使用されます。運は一般的な用語ですが、バイナリミューテックスをロックとして使用できます。最新のC++では、lock_guardおよび同様のオブジェクトを使用して、RAIIを利用し、ミューテックスの使用を簡素化して安全にします。条件付き変数は、モニターとして何かを知らせるためにミューテックスと組み合わされることが多い別のプリミティブです。

これらのどれ(cv、mutex、lock)をいつ使用するかを理解するのに苦労しています。誰かがリソースを説明または指摘できますか?

ミューテックスを使用して、何かへの相互排他アクセスを保証します。これは、さまざまな並行性の問題に対するデフォルトのソリューションです。ミューテックスで保護したいC++のスコープがある場合は、lock_guardを使用します。ミューテックスはlock_guardによって処理されます。スコープにlock_guardを作成し、ミューテックスで初期化するだけで、C++が残りの作業を行います。スコープがスタックから削除されると、例外のスローや関数からの復帰などの理由で、ミューテックスが解放されます。これはRAIIの背後にある考え方であり、lock_guardは別のリソースハンドラーです。

ミューテックスを使用するだけでは簡単に解決できない同時実行の問題がいくつかあります。または単純なソリューションは、複雑さや非効率につながる可能性があります。たとえば、生産者問題はその1つです。プロデューサーと共有されているバッファーからアイテムを読み取るコンシューマースレッドを実装する場合は、ミューテックスでバッファーを保護する必要がありますが、条件変数を使用せずに、ミューテックスをロックし、バッファーをチェックして、アイテムが空でない場合は読み取る必要があります、ロックを解除してしばらく待ってから、もう一度ロックして続行します。バッファが空であることが多く(ビジーウェイト)、また多くのロックとロック解除があり、スリープ状態になると、時間の無駄になります。

The solution we need for the producer-consumer problem must be simpler and more efficient. A monitor (a mutex + a conditional variable) helps us here. We still need a mutex to guarantee mutual exclusive access but a conditional variable lets us sleep and wait for a certain condition. The condition here is the producer adding an item to the buffer. The producer thread notifies the consumer thread that there is and item in the buffer and the consumer wakes up and gets the item. Simply, the producer locks the mutex, puts something in the buffer, notifies the consumer. The consumer locks the mutex, sleeps while waiting for a condition, wake s up when there is something in the buffer and gets the item from the buffer. It's a simpler and more efficient solution.

次に同時実行の問題に直面したときは、次のように考えてください。何かへの相互排他アクセスが必要な場合は、ミューテックスを使用してください。より安全でシンプルにしたい場合は、lock_guardを使用してください。問題に、別のスレッドで発生しなければならない条件を待つ手がかりがある場合は、条件変数が必要になる場合があります。

一般的な経験則として、最初に問題を分析し、あなたと同様の有名な同時実行の問題を見つけてください(たとえば、このページの同期の古典的な問題のセクションを参照してください)。よく知られているソリューションで提案されているソリューションについて読んで、最良のソリューションをピークにしましょう。カスタマイズが必要な場合があります。

于 2019-09-12T10:28:50.450 に答える