7

バイナリセマフォとミューテックスについて読んでいるときに、次の違いを見つけました。

どちらも値 0 と 1 を持つことができますが、ミューテックス ロックを取得した同じスレッドによってミューテックスのロックを解除できます。ミューテックス ロックを取得するスレッドは、優先順位の高いプロセスが同じミューテックスを取得しようとする場合に優先順位を逆転させることができますが、これはバイナリ セマフォには当てはまりません。

では、バイナリ セマフォはどこで使用すればよいのでしょうか。誰でも例を挙げることができますか?

編集:私は両方の働きを理解したと思います。基本的に、バイナリ セマフォは同期を提供しますが、mutex はロック メカニズムを提供します。より明確にするために、Galvin OSの本からいくつかの例を読みました。

4

3 に答える 3

6

バイナリセマフォが非常に役立つと思う典型的な状況の1つは、スレッドが親スレッドが所有する構造から読み取るスレッドの初期化です。親スレッドは、新しいスレッドが構造から共有データを読み取るのを待ってから、構造の存続期間を終了させる必要があります(たとえば、スコープを離れることによって)。バイナリセマフォを使用する場合は、セマフォ値をゼロに初期化し、親が待機している間に子に投稿させるだけです。セマフォがなければ、ミューテックスと条件変数、およびそれらを使用するためのはるかに醜いプログラムロジックが必要になります。

于 2012-07-17T18:04:50.097 に答える
3

ほとんどの場合、バイナリ セマフォを使用して、ロックせずに他のスレッドに通知します。

同期リクエストの簡単な使用例:

スレッド 1 :

Semaphore sem;
request_to_thread2(&sem); // Function sending request to thread2 in any fashion
sem.wait();               // Waiting request complete

スレッド 2 :

Semaphore *sem;
process_request(sem);     // Process request from thread 1
sem->post();              // Signal thread 1 that request is completed

注: スレッド 2 処理でセマフォをポストする前に、追加の同期なしで安全にスレッド 1 データを設定できます。

于 2012-07-17T20:31:23.110 に答える
1

バイナリ ミューテックスの代わりにカウント セマフォを使用する標準的な例は、a) 交換可能で、b) 複数の利用可能なリソースの数が限られている場合です。

たとえば、一度に最大 10 人のリーダーがデータベースにアクセスできるようにする場合は、10 に初期化されたカウント セマフォを使用して、リソースへのアクセスを制限できます。各リーダーは、リソースにアクセスする前にセマフォを取得して、使用可能なカウントを減らす必要があります。カウントが 0 になると (つまり、10 人のリーダーがデータベースにアクセスし、まだデータベースを使用している)、他のすべてのリーダーはロックアウトされます。リーダーが終了すると、セマフォ カウントを 1 増やして、リソースを使用しなくなったことを示し、他のリーダーがセマフォ ロックを取得して代わりにアクセスできるようになります。

ただし、カウントされたセマフォは、他のすべての同期プリミティブと同様に、多くのユース ケースがあり、枠にとらわれずに考えるだけの問題です。ミューテックスと追加のロジックで解決することに慣れている多くの問題が、セマフォを使用するとより簡単かつ簡単に実装できることに気付くかもしれません。ミューテックスはセマフォのサブセットです。つまり、ミューテックスでできることはすべてセマフォで行うことができます (カウントを 1 に設定するだけです)。ミューテックスだけではできません。

結局のところ、通常は、1 つの同期プリミティブで十分です (スレッド同期の "turing-complete" と考えてください)。ただし、それぞれが異なるアプリケーションに合わせて調整されており、いくつかのカスタマイズと追加の接着剤を使用して入札を強制することはできますが、別の同期プリミティブの方がジョブにより適している可能性があります。

于 2012-07-17T18:11:09.393 に答える