それぞれについて説明するリアルタイムのシナリオをいただければ幸いです。pthread でこれらとは別に同期を処理する他の方法はありますか。ミューテックスは再帰的ミューテックス (リアルタイムのシナリオ) とどう違うのですか?
2 に答える
ミューテックスを使用して、共有リソース (変数、ファイル、周辺機器) を、一貫性のない状態のままにする可能性のある変更から保護できます。
セマフォを使用して、同一の共有リソースの有限プールを管理できます (この重要なケースの 1 つにIPC キューがあります)。スレッドは、プールからリソースを取得したり、リソースをプールに追加したり、リソースが使用可能になるまで待機したりできます。セマフォに加えてミューテックスを使用する必要がある場合があることに注意してください (プールのデータ構造自体を保護するため)。
読み取り/書き込みロックは、読み取りまたは書き込み (変更) 可能な共有リソースを保護するために使用できます。すべてのリーダー スレッドが同時にアクセスできます。書き込みスレッドには排他アクセスが必要です。
条件変数をミューテックスと一緒に使用して、イベントを通知できます。
ウィキペディアを使用して、このほとんどについて読むことができます。
boost::interprocess
これはドキュメントで非常に明確に答えられています
ミューテックスとは
Mutex は相互排除の略で、プロセス間の同期の最も基本的な形式です。ミューテックスは、1 つのスレッドだけが特定のミューテックスをロックできることを保証します。コード セクションがミューテックスのロックとロック解除で囲まれている場合、一度に 1 つのスレッドだけがコードのそのセクションを実行することが保証されます。そのスレッドがミューテックスのロックを解除すると、他のスレッドがそのコード領域に入ることができます。
//ミューテックスは以前に構築されています
lock_the_mutex();
//このコードは一度に 1 つのスレッドによってのみ実行されます。
unlock_the_mutex(); ミューテックスは、再帰的または非再帰的でもあります。
再帰的ミューテックスは、同じスレッドによって複数回ロックされる可能性があります。ミューテックスを完全にロック解除するには、スレッドがミューテックスをロックしたのと同じ回数ロックを解除する必要があります。非再帰的ミューテックスは、同じスレッドによって複数回ロックすることはできません。ミューテックスがスレッドによって 2 回ロックされた場合、結果は未定義であり、エラーがスローされるか、スレッドが永久にブロックされる可能性があります。インタープロセス ドキュメントの強化
と
セマフォとは?
セマフォは、次の 2 つの基本操作を提供する内部カウントに基づくプロセス間の同期メカニズムです。
待機: セマフォ カウントの値をテストし、値が 0 以下の場合は待機します。それ以外の場合は、セマフォ カウントをデクリメントします。Post: セマフォ数を増やします。いずれかのプロセスがブロックされている場合、それらのプロセスの 1 つが起動されます。初期セマフォ数が 1 に初期化されている場合、Wait 操作はミューテックスのロックに相当し、Post はミューテックスのロック解除に相当します。このタイプのセマフォは、バイナリ セマフォと呼ばれます。
セマフォはミューテックスのように使用できますが、独自の機能があります。ミューテックスとは異なり、待機操作を実行したのと同じスレッド/プロセスで Post 操作を実行する必要はありません。 ブースト::プロセス間のドキュメント
ブーストインタープロセスには、リーダーライターロックと呼ばれるものが明示的にありませんがshared_locks
、 、 、およびupgrade_lock
を使用してそれらを実装しますupgrade_to_unique lock
共有可能およびアップグレード可能なミューテックスとは?
共有可能でアップグレード可能なミューテックスは、通常のミューテックスよりも多くのロックの可能性を提供する特別なミューテックス タイプです。データの読み取りとデータの変更を区別できる場合があります。一部のスレッドのみがデータを変更する必要があり、データを同時アクセスから保護するために単純なミューテックスが使用されている場合、同時実行性はかなり制限されます。データを読み取るだけの 2 つのスレッドは、同時に実行される代わりにシリアル化されます。
データを読み取るだけのスレッドへの同時アクセスを許可し、読み取りと変更を行うスレッド間、または変更するスレッド間の同時アクセスを回避すると、パフォーマンスを向上させることができます。これは特に、データの変更よりもデータの読み取りが一般的であり、同期されたデータ読み取りコードの実行に時間がかかるアプリケーションに当てはまります。共有可能なミューテックスを使用すると、2 つのロック タイプを取得できます。
排他ロック: 普通のミューテックスに似ています。スレッドが排他ロックを取得すると、排他ロックが解放されるまで、他のスレッドはロック (排他またはその他) を取得できません。他のスレッドが排他的以外のロックを持っている場合、排他的ロックを取得しようとするスレッドはブロックされます。このロックは、データを変更するスレッドによって取得されます。共有可能ロック: スレッドが共有可能ロックを取得すると、他のスレッドは排他ロックを取得できなくなります。いずれかのスレッドが排他ロックを取得した場合、共有可能なロックを取得しようとするスレッドはブロックされます。このロックは、データを読み取る必要があるスレッドによって実行されます。アップグレード可能なミューテックスを使用すると、以前のロックと新しいアップグレード可能なロックを取得できます。
アップグレード可能なロック: アップグレード可能なロックを取得することは、特権付きの共有可能なロックを取得することに似ています。スレッドがアップグレード可能なロックを取得すると、他のスレッドが共有可能なロックを取得できます。いずれかのスレッドが排他的またはアップグレード可能なロックを取得した場合、アップグレード可能なロックを取得しようとするスレッドはブロックされます。アップグレード可能なロックを取得したスレッドは、共有可能なロックを取得した他のスレッドがそれを解放したときに、排他ロックをアトミックに取得できることが保証されます。これは、データを変更する必要がある可能性があるが、通常はデータを読み取るだけでよいスレッドに使用されます。このスレッドはアップグレード可能なロックを取得し、他のスレッドは共有可能なロックを取得できます。アップグレード可能なスレッドがデータを読み取り、それを変更する必要がある場合、スレッドを昇格させて排他ロックを取得できます。すべての共有可能なスレッドが共有可能なロックを解放すると、アップグレード可能なロックはアトミックに排他ロックに昇格します。新しくプロモートされたスレッドはデータを変更でき、移行中に他のスレッドがデータを変更していないことを確認できます。アップグレード可能な (特権リーダー) ロックを取得できるスレッドは 1 つだけです。 インタープロセス ドキュメントの強化
C++ 自体にはまだreader-writer locks
(共有ミューテックスを使用して) ありませんが、@Howard Hinnet はそれらをそこに入れようとしました。ここを見ると、彼はコードも提供しています
C++ にはセマフォがなく、ミューテックスは私の知る限り、新しい C++11 標準にのみ含まれています。boost::interprocess