web-dev-qa-db-ja.com

バイナリセマフォとミューテックスの違い

バイナリセマフォとミューテックスの間に違いはありますか、それとも本質的に同じですか?

741
Nitin

それらは _ _ ではなく同じものです。それらはさまざまな目的に使用されます。
両方のタイプのセマフォはフル/エンプティ状態を持ち、同じAPIを使用しますが、使用方法は大きく異なります。

相互排除セマフォ
相互排除セマフォは、共有リソース(データ構造、ファイルなど)を保護するために使用されます。

ミューテックスセマフォは、それを受け取るタスクによって「所有」されています。タスクBが現在タスクAによって保持されているミューテックスをsemMiveしようとすると、タスクBの呼び出しはエラーを返して失敗します。

ミューテックスは常に以下のシーケンスを使用します。

  -  SemTake 
  - 重要セクション
  -  SemGive

これは簡単な例です:

スレッドAスレッドB 
ミューテックス
アクセスデータ
 ...ミューテックス<==ブロック
 ... 
をブロックします。 ]ミューテックスアクセスデータを与える<==ブロックを解除する
 ... 
ミューテックスを与える

バイナリセマフォ
バイナリセマフォはまったく異なる質問に答えます。

  • タスクBは、何かが起こるのを待って保留されています(たとえば、センサーがトリップしている)。
  • センサートリップと割り込みサービスルーチンが実行されます。それは旅行の仕事に通知する必要があります。
  • タスクBが実行され、センサートリップのために適切な行動をとるべきです。それから待ってください。

   Task A                      Task B
   ...                         Take BinSemaphore   <== wait for something
   Do Something Noteworthy
   Give BinSemaphore           do something    <== unblocks

バイナリセマフォでは、Bがセマフォを取り、Aがそれを渡すことは問題ありません。
やはり、バイナリセマフォはリソースをアクセスから保護していません。セマフォを与えたり取ったりするという行為は、基本的に切り離されています。
同じバイナリセマフォをあきらめることと取ることは、同じタスクにとってほとんど意味がありません。

635
Benoit

トイレの例 は楽しい例えです。

ミューテックス:

トイレへの鍵です。一度に1人が鍵を持つことができます - トイレを占有します - 。終了すると、その人はキュー内の次の人にキーを渡します(解放します)。

「ミューテックスは通常、複数のスレッドで同時に実行できないリエントラントコードのセクションへのアクセスを直列化するために使用されます。ミューテックスオブジェクトは、1つのスレッドを制御セクションにしか許可せず、他のスレッドにアクセスを試みます。そのセクションは、最初のスレッドがそのセクションから出るまで待機します。」参照:Symbian開発者ライブラリ

(ミューテックスは実際には値1のセマフォです。)

セマフォ:

無料の同一のトイレの鍵の数です。例として、同じ鍵と鍵を備えた4つのトイレがあるとします。セマフォの数(キーの数)は最初は4に設定されています(4つのトイレはすべて空いています)。その後、人々が入ってくるとカウント値が減少します。空きキーがなくなり、セマフォの数は0になります。一人の人がトイレを離れると、セマフォは1(1つのフリーキー)に増加され、キューの次の人に渡されます。

「セマフォは共有リソースの同時ユーザー数を最大数に制限します。スレッドはリソースへのアクセスを要求し(セマフォを減少させ)、リソースの使用を終了したことを知らせることができます(セマフォを増加させます)。 「参照:Symbian開発者ライブラリ

416
dlinsin

ミューテックスは、それを取得したスレッドによってのみ解放されますが、他のスレッド(またはプロセス)からセマフォを通知することはできます。そのため、セマフォはプロデューサ/コンシューマなどの同期の問題に適しています。

Windowsでは、バイナリセマフォはミューテックスよりもイベントオブジェクトに似ています。

411

トピックに関する素晴らしい記事:

パート2から:

ミューテックスは、バイナリセマフォの原則と似ていますが、1つの大きな違いがあります。所有の原則です。所有権とは、タスクがミューテックスだけをロック(獲得)したときに、それをロック解除(解放)できるという単純な概念です。タスクがロックされていないミューテックスのロックを解除しようとした場合(つまり所有していない場合)、エラー状態が発生し、最も重要なのはミューテックスのロックが解除されないことです。相互排除オブジェクトが所有権を持っていなければ、それが呼ばれるものとは無関係に、それはミューテックスではありません。

139
teki

上記の答えのどれも混乱を解消しないので、ここに私の混乱を解消したものがあります。

厳密に言えば、 ミューテックスはロックメカニズムです はリソースへのアクセスを同期させるために使用されます。ミューテックスを獲得できるのは、1つのタスク(OS抽象化に基づくスレッドまたはプロセス)だけです。これはミューテックスに関連した所有権があり、所有者だけがロックを解除できることを意味します(ミューテックス)。

セマフォはシグナル伝達メカニズムです (「完了しました。続行できます」一種のシグナル)。たとえば、携帯電話で曲を聴いていて(同時に1つのタスクと見なして)、友達があなたに電話をかけた場合、割り込みがトリガされ、割り込みサービスルーチン(ISR)が呼び出し処理タスクにウェイクアップを通知します。 。

出典: http://www.geeksforgeeks.org/mutex-vs-semaphore/ /

92
Hemant

同期のセマンティクスは大きく異なります。

  • ミューテックスは、特定のリソースへのアクセスのシリアル化を許可します。つまり、複数のスレッドが一度に1つずつロックを待機し、前述のように、スレッドownsまでロックをonlyこの特定のスレッドはロックを解除できます。
  • バイナリセマフォは、値0および1を持つカウンタです。anyタスクがsem_postを実行するまで、タスクはブロックします。セマフォは、リソースが利用可能であることを通知し、利用可能として通知されるまで待機するメカニズムを提供します。

そのため、ミューテックスはタスクからタスクに渡されるトークンとして、セマフォは赤信号として処理されます(それはsignals処理を続行できる人)。

39
ppi
  • 定義上、 Mutex は、複数のスレッドで同時に実行できないリエントラントコードのセクションへのアクセスをシリアル化するために使用されます。

  • A セマフォ は、定義上、共有リソースの同時ユーザー数を最大数までに制限します。

  • セマフォをミューテックスにすることはできますが、ミューテックスをセマフォにすることはできません。これは単にバイナリセマフォをミューテックスとして使用できることを意味しますが、ミューテックスはセマフォの機能を発揮することはできません。

  • セマフォとMutex(少なくとも最新のカーネル)はどちらも本質的に再帰的ではありません。
  • 誰もセマフォを所有していませんが、ミューテックスは所有しており、所有者はそれらに対して責任を負います。これはデバッグの観点から見た重要な違いです。
  • ミューテックスの場合、ミューテックスを所有するスレッドがそれを解放する責任があります。ただし、セマフォの場合、この条件は必須ではありません。他のスレッドは、s m p s(function.e_ot)を使用してセマフォを解放するように通知できます。

  • 開発者にとって重要なもう1つの違いは、セマフォはシステム全体に適用され、他の方法でクリーンアップされない限り、ファイルシステム上にファイルの形で残ることです。ミューテックスはプロセス全体を処理し、プロセスが終了すると自動的にクリーンアップされます。

  • セマフォの性質により、スレッド間だけでなく、関連プロセスと無関係プロセスとの同期にそれらを使用することが可能になります。 Mutexは、スレッド間および最大で関連プロセス間でのみ同期できます(最新のカーネルのpthread実装には、関連プロセス間でMutexを使用できるようにする機能が付属しています)。
  • カーネルの文書によると、Mutexはセマフォに比べて軽量です。これが意味するのは、Mutexを持つプログラムと比較した場合、セマフォを使用するプログラムはより高いメモリフットプリントを持つということです。
  • 使用法の観点からすると、Mutexはセマフォと比べてより単純なセマンティクスを持ちます。
35
Varun Chhangani

理論的レベルでは、それらは意味的に違いはありません。セマフォを使ってミューテックスを実装することも、その逆も可能です(例は ここ を参照)。実際には、実装は異なり、それらはわずかに異なるサービスを提供します。

(それらを取り巻くシステムサービスに関して)実際的な違いは、ミューテックスの実装がより軽量の同期メカニズムであることを目的としているということです。 Oracleの話では、ミューテックスは ラッチ として、セマフォは wait として知られています。

最低レベルでは、それらはある種のアトミック テストとセット メカニズムを使用します。これはメモリ位置の現在の値を読み、ある種の条件を計算し、そして 中断することができないという単一の命令でその位置に値を書き出す 。これは、ミューテックスを取得して、他の誰かがあなたの前にそれを持っているかどうかを確認するためにテストできることを意味します。

典型的なミューテックスの実装は、テストと設定の命令を実行し、他の何かがミューテックスを設定したかどうかを評価するプロセスまたはスレッドを持っています。ここで重要な点は、 スケジューラ とのやり取りがないことです。そのため、誰がロックを設定したのかわからない(そして気にしないでください)。それから、タイムスライスを放棄してタスクが再スケジュールされたときにもう一度試みるか、 spin-lock を実行します。スピンロックは次のようなアルゴリズムです。

Count down from 5000:
     i. Execute the test-and-set instruction
    ii. If the mutex is clear, we have acquired it in the previous instruction 
        so we can exit the loop
   iii. When we get to zero, give up our time slice.

保護されたコード( クリティカルセクション と呼ばれる)の実行が終了したら、ミューテックス値をゼロに設定するか、「クリア」を意味するものを設定します。複数のタスクがミューテックスを取得しようとしている場合は、ミューテックスが解放された後にスケジュールされている次のタスクがリソースにアクセスします。通常、排他的アクセスがごく短時間しか必要とされない場合、通常は共有データ構造を更新するために、ミューテックスを使用して同期リソースを制御します。

セマフォは、ミューテックスライブラリよりも少し深くスケジューラと対話するカウントといくつかのシステムコールラッパーを持つ同期データ構造(通常ミューテックスを使用)です。セマフォはインクリメントおよびデクリメントされ、何か他の準備が整うまで ブロック タスクに使用されます。この簡単な例については、 生産者/消費者問題 を参照してください。セマフォは何らかの値に初期化されます - バイナリセマフォは、セマフォが1に初期化されるという特別な場合です。セマフォへの投稿は、待機中のプロセスを起こすという効果があります。

基本的なセマフォアルゴリズムは次のようになります。

(somewhere in the program startup)
Initialise the semaphore to its start-up value.

Acquiring a semaphore
   i. (synchronised) Attempt to decrement the semaphore value
  ii. If the value would be less than zero, put the task on the tail of the list of tasks waiting on the semaphore and give up the time slice.

Posting a semaphore
   i. (synchronised) Increment the semaphore value
  ii. If the value is greater or equal to the amount requested in the post at the front of the queue, take that task off the queue and make it runnable.  
 iii. Repeat (ii) for all tasks until the posted value is exhausted or there are no more tasks waiting.

バイナリセマフォの場合、両者の主な実用上の違いは、実際のデータ構造を取り巻くシステムサービスの性質です。

編集:evanが正しく指摘したように、スピンロックはシングルプロセッサマシンを遅くするでしょう。シングルプロセッサでは、mutexを保持しているプロセスが別のタスクの実行中にそれをリセットすることは決してないため、マルチプロセッサボックスでのみスピンロックを使用します。スピンロックはマルチプロセッサアーキテクチャでのみ有用です。

ミューテックスとセマフォは同期プリミティブとして使用されますが、大きな違いがあります。ミューテックスの場合は、ミューテックスをロックまたは獲得したスレッドだけがロックを解除できます。セマフォの場合、セマフォを待っているスレッドは別のスレッドによって通知される可能性があります。一部のオペレーティングシステムは、プロセス間でのミューテックスとセマフォの使用をサポートしています。通常、使用方法は共有メモリに作成されます。

18
Praveen_Shukla

ミューテックス:スレッドT1がアクセスしたいクリティカルセクションがあるとします。 T1:

  1. ロック
  2. クリティカルセクションを使用
  3. ロック解除

バイナリセマフォ:シグナル待ちとシグナルに基づいて動作します。 wait "s"の値を1つ減らす通常 "s"の値は "1"の値で初期化され、signalは "s"の値を1つ増やします。 "s"の値が1の場合、誰もクリティカルセクションを使用していないことを意味し、値が0の場合、クリティカルセクションが使用中であることを意味します。スレッドT2がクリティカルセクションを使用していると仮定すると、それは以下のステップに従う。 T2:

  1. wait(s)//最初のsの値は、waitを呼び出した後の値が1、すなわち0になります。
  2. クリティカルセクションを使用
  3. signal(s)// sの値が増えて1になる

MutexとBinaryセマフォの主な違いは、スレッドがクリティカルセクションをロックしている場合はMutextにあり、クリティカルセクションをロック解除する必要はありません。 sの値が1になるまで、sの値が1になると、sの値が1になり、他の関数がクリティカルセクションを使用できるようになります。したがって、バイナリセマフォではスレッドは所有権を持ちません。

11
Sumit Naik

あなたは明らかにmutexを使ってあるスレッドのデータを別のスレッドから同時にアクセスされるようにロックします。 lock()を呼び出したばかりで、データにアクセスしているとします。これは、他のスレッド(または同じスレッドコードの別のインスタンス)が同じミューテックスによってロックされている同じデータにアクセスすることを期待していないことを意味します。つまり、同じスレッドコードが別のスレッドインスタンス上で実行されるのであれば、ロックを打つと、lock()はそこで制御フローをブロックするはずです。これは、異なるスレッドコードを使用するスレッドにも適用されます。これは、同じデータにもアクセスしており、同じミューテックスによってロックされています。この場合、あなたはまだデータにアクセスしている最中で、ミューテックスロック解除に達するまでにさらに15秒かかるかもしれません(ミューテックスロックでブロックされている他のスレッドがブロック解除され、コントロールがデータにアクセスします。さらに別のスレッドが同じミューテックスのロックを解除し、そのミューテックスロックですでに待機している(ブロックしている)スレッドがデータのブロックを解除してアクセスすることを許可しますか。あなたが私がここで言っていることを得たことを望みますか?に従って、普遍的な定義に同意しました!、

  • 「ミューテックス」ではこれは起こり得ない。他のスレッドが自分のスレッドのロックを解除することはできません。
  • 「バイナリセマフォ」ではこれが起こる可能性があります。他のスレッドが自分のスレッドのロックを解除することができます

ですから、mutexの代わりにバイナリセマフォを使うことに特に興味があるのなら、ロックとロック解除を "スコープにする"際には細心の注意を払うべきです。つまり、すべてのロックをヒットするすべての制御フローがロック解除呼び出しを実行する必要があります。また、「最初のロック解除」を行うべきではなく、常に「最初のロック」を行うべきです。

10
paxi

ミューテックスは「ロック機構」に使用されます。一度に1つのプロセスが共有リソースを使用できます

一方

セマフォは、「完了しました。続行できます」などの「シグナリングメカニズム」に使用されます。

10
Jamshad Ahmad

Windowsでは、ミューテックスとバイナリセマフォには2つの違いがあります。

  1. ミューテックスは、所有権を持つスレッド、つまり以前にWait関数を呼び出した(または作成時に所有権を取得した)スレッドによってのみ解放できます。セマフォはどのスレッドからも解放できます。

  2. スレッドは、ブロックせずにミューテックス上でwait関数を繰り返し呼び出すことができます。ただし、セマフォを解放せずにバイナリセマフォに対してwait関数を2回呼び出した場合、スレッドはブロックされます。

10
Rich

神話:

「バイナリーセマフォとミューテックスは同じ」または「値1のセマフォはミューテックスです」と書かれていますが、ミューテックスはそれを獲得したスレッドによってのみ解放されます

キーポイント:

•スレッドは複数のロックを獲得できます(Mutex)。

•再帰ミューテックス、ここではミューテックスのロックとロック解除を同じにする必要がある場合にのみ、ミューテックスを複数回ロックできます。

•すでにミューテックスをロックしていたスレッドが、再度ミューテックスをロックしようとすると、そのミューテックスの待機リストに入り、デッドロックが発生します。

•バイナリセマフォとミューテックスは似ていますが同じではありません。

•ミューテックスはそれに関連した保護プロトコルのために高価な操作です。

•ミューテックスの主な目的は、アトミックアクセスまたはリソースのロックを実現することです。

9
Saurabh Sinha

Mutexは、単一の共有リソースへのアクセスを制御します。それはacquire()そのリソースへのアクセスとrelease()それへのアクセスを提供します。

Semaphoreは、リソースの共有プールへのアクセスを制御します。プール内のリソースの1つが使用可能になるまでWait()に操作を提供し、プールに戻されたときにSignal()に操作を提供します。

セマフォが保護するリソースの数が1より大きい場合、それはCounting Semaphoreと呼ばれます。 1つのリソースを制御するときは、Boolean Semaphoreと呼ばれます。ブールセマフォはミューテックスと同等です。

したがって、セマフォはミューテックスよりも高レベルの抽象概念です。ミューテックスはセマフォを使って実装できますが、その逆はできません。

8
Charan

修正された質問は - ミューテックスと "Linux"の "バイナリ"セマフォの違いは何ですか?

回答:以下が違いです。 - スコープ - ミューテックスのスコープは、それを作成したプロセスアドレス空間内にあり、スレッドの同期に使用されます。セマフォはプロセス空間全体で使用できるため、プロセス間同期に使用できます。

ii)ミューテックスはセマフォより軽量で高速です。 Futexはさらに速いです。

iii)ミューテックスは、同じスレッドによって同じ回数解放されなければならないという条件で、複数回正常に獲得されます。獲得しようとしている他のスレッドはブロックします。セマフォの場合、同じプロセスが再度取得しようとすると、1回しか取得できないためブロックされます。

6
Mickey

ミューテックスはクリティカル領域のブロックに取り組んでいますが、セマフォはカウントに取り組んでいます。

6
Askkan

バイナリセマフォとミューテックスの違い:OWNERSHIP: セマフォは、現在の所有者でなくても通知(投稿)できます。あなたは所有者ではありませんが、他のどのスレッドからでも投稿できるということです。

セマフォは処理中のパブリックプロパティです。所有者以外のスレッドによって単純に投稿されることがあります。この違いを太字でマークしてください。たくさんの意味があります。

5
buddingspacer

http://www.geeksforgeeks.org/archives/9102 で詳細を説明しています。

Mutexは、リソースへのアクセスを同期するために使用されるロックメカニズムです。 Semaphoreはシグナル伝達機構です。

彼/彼女がミューテックスの代わりにバイナリセマフォを使いたいのであれば、プログラマ次第です。

5
user1852497

Windowsでは違いは以下の通りです。 MUTEX: 正常に実行されるプロセス wait signal を実行する必要があり、その逆の場合も同様です。 バイナリセマフォ: 異なるプロセスはセマフォに対して wait または signal 操作を実行できます。

4
ajay bidari

ミューテックスが所有者を持っているという事実は別として、2つのオブジェクトは異なる用法のために最適化されるかもしれません。ミューテックスは短期間だけ保持されるように設計されています。これに違反すると、パフォーマンスが低下し、スケジュールが不正になる可能性があります。たとえば、実行中のスレッドが別のスレッドですでにブロックされていても、ミューテックスの取得を許可されている可能性があります。セマフォはより公平性を提供するか、またはいくつかの条件変数を使用して公平性を強制することができます。

4
jilles

上記の記事を読み終えた後、その概念は私には明らかでした。しかし、いくつかの疑問が残っていました。だから、私はこの小さなコードを書いた。

我々がそれを取らずにセマフォを与えようとすると、それは通り抜けます。しかし、あなたがそれを取らずにミューテックスを与えようとすると、それは失敗します。私はこれをWindowsプラットフォームでテストしました。 MUTEXを使用して同じコードを実行するには、USE_MUTEXを有効にします。

#include <stdio.h>
#include <windows.h>
#define xUSE_MUTEX 1
#define MAX_SEM_COUNT 1

DWORD WINAPI Thread_no_1( LPVOID lpParam );
DWORD WINAPI Thread_no_2( LPVOID lpParam );

HANDLE Handle_Of_Thread_1 = 0;
HANDLE Handle_Of_Thread_2 = 0;
int Data_Of_Thread_1 = 1;
int Data_Of_Thread_2 = 2;
HANDLE ghMutex = NULL;
HANDLE ghSemaphore = NULL;


int main(void)
{

#ifdef USE_MUTEX
    ghMutex = CreateMutex( NULL, FALSE, NULL);
    if (ghMutex  == NULL) 
    {
        printf("CreateMutex error: %d\n", GetLastError());
        return 1;
    }
#else
    // Create a semaphore with initial and max counts of MAX_SEM_COUNT
    ghSemaphore = CreateSemaphore(NULL,MAX_SEM_COUNT,MAX_SEM_COUNT,NULL);
    if (ghSemaphore == NULL) 
    {
        printf("CreateSemaphore error: %d\n", GetLastError());
        return 1;
    }
#endif
    // Create thread 1.
    Handle_Of_Thread_1 = CreateThread( NULL, 0,Thread_no_1, &Data_Of_Thread_1, 0, NULL);  
    if ( Handle_Of_Thread_1 == NULL)
    {
        printf("Create first thread problem \n");
        return 1;
    }

    /* sleep for 5 seconds **/
    Sleep(5 * 1000);

    /*Create thread 2 */
    Handle_Of_Thread_2 = CreateThread( NULL, 0,Thread_no_2, &Data_Of_Thread_2, 0, NULL);  
    if ( Handle_Of_Thread_2 == NULL)
    {
        printf("Create second thread problem \n");
        return 1;
    }

    // Sleep for 20 seconds
    Sleep(20 * 1000);

    printf("Out of the program \n");
    return 0;
}


int my_critical_section_code(HANDLE thread_handle)
{

#ifdef USE_MUTEX
    if(thread_handle == Handle_Of_Thread_1)
    {
        /* get the lock */
        WaitForSingleObject(ghMutex, INFINITE);
        printf("Thread 1 holding the mutex \n");
    }
#else
    /* get the semaphore */
    if(thread_handle == Handle_Of_Thread_1)
    {
        WaitForSingleObject(ghSemaphore, INFINITE);
        printf("Thread 1 holding semaphore \n");
    }
#endif

    if(thread_handle == Handle_Of_Thread_1)
    {
        /* sleep for 10 seconds */
        Sleep(10 * 1000);
#ifdef USE_MUTEX
        printf("Thread 1 about to release mutex \n");
#else
        printf("Thread 1 about to release semaphore \n");
#endif
    }
    else
    {
        /* sleep for 3 secconds */
        Sleep(3 * 1000);
    }

#ifdef USE_MUTEX
    /* release the lock*/
    if(!ReleaseMutex(ghMutex))
    {
        printf("Release Mutex error in thread %d: error # %d\n", (thread_handle == Handle_Of_Thread_1 ? 1:2),GetLastError());
    }
#else
    if (!ReleaseSemaphore(ghSemaphore,1,NULL) )      
    {
        printf("ReleaseSemaphore error in thread %d: error # %d\n",(thread_handle == Handle_Of_Thread_1 ? 1:2), GetLastError());
    }
#endif

    return 0;
}

DWORD WINAPI Thread_no_1( LPVOID lpParam ) 
{ 
    my_critical_section_code(Handle_Of_Thread_1);
    return 0;
}


DWORD WINAPI Thread_no_2( LPVOID lpParam ) 
{
    my_critical_section_code(Handle_Of_Thread_2);
    return 0;
}
4
Raghav Navada

バイナリセマフォがミューテックスとして使用されるかもしれない間、ミューテックスはミューテックスをロックしたプロセスだけがそれをロック解除することになっているという点で、より特定のユースケースです。この所有権の制約により、以下に対する保護を提供できます。

  • 偶然の解放
  • 再帰的デッドロック
  • タスクデスデッドロック

速度が低下するため、これらの制約は常に存在するわけではありません。コードの開発中に、これらのチェックを一時的に有効にすることができます。

例えばあなたのミューテックスでError check属性を有効にすることができます。同じものを2回ロックしようとすると、ミューテックスのエラーチェックでEDEADLKが返され、自分のものではないミューテックスのロックを解除するとEPERMが返されます。

pthread_mutex_t mutex;
pthread_mutexattr_t attr;
pthread_mutexattr_init (&attr);
pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK_NP);
pthread_mutex_init (&mutex, &attr);

初期化したら、次のようにこれらのチェックをコードに配置できます。

if(pthread_mutex_unlock(&mutex)==EPERM)
 printf("Unlock failed:Mutex not owned by this thread\n");
3
Adi06411

ミューテックスは機密コードとデータを保護するために使用され、セマフォは同期化に使用されます。機密コードを保護することで実用的に使用することもできますが、操作によって他のスレッドによる保護を解除する危険があります。バイセマフォとミューテックスの違いは所有権です。例えば、ミューテックスはトイレに入ってドアをロックすることができ、男が出るまで誰も入ることができない、バイセマフォは入ることができるようなものです。トイレとドアをロックしますが、他の誰かが管理者にドアを開けるように頼むことによって入ることができます、それはばかげています。

2
mannnnerd

Mutex

通常、ミューテックスは、複数のスレッドで同時に実行できない再入可能コードのセクションへのアクセスをシリアル化するために使用されます。ミューテックスオブジェクトは1つのスレッドのみを制御セクションに許可し、そのセクションにアクセスしようとする他のスレッドに、そのセクションから最初のスレッドが終了するまで待機させます。ミューテックスの適切な使用は、共有リソースを保護するために危険です意図しない副作用。異なる優先度で動作し、ミューテックスを介して調整する2つのRTOSタスクは、優先度反転の機会を作成します。 Mutexはユーザースペースで動作します。

セマフォ

セマフォはシグナリングメカニズムです。セマフォは、共有リソースの同時ユーザー数を最大数に制限します。スレッドは、リソースへのアクセスを要求(セマフォをデクリメント)し、リソースの使用が終了したことを通知(セマフォをインクリメント)できます。複数のスレッドが共有リソースにアクセスできるようにします。セマフォの正しい使用法は、1つのタスクから別のタスクへのシグナル伝達です。セマフォは割り込みサービスルーチン =(ISR)をタスクに。セマフォへのシグナル送信は非ブロッキングRTOS動作であるため、ISRセーフです。この手法により、エラーが発生しやすいタスクレベルで割り込みを無効にする必要がないため、カーネルスペースで機能します。

1
Gopika BG

セマフォとは異なり、ミューテックスには所有権があります。ミューテックスの範囲内のスレッドはロック解除されたミューテックスを取得し、コードの同じクリティカルセクションへのアクセスをロックできますが、ミューテックスをロックしたスレッドのみshould =ロックを解除します

1
laksbv

ミューテックスとバイナリセマフォはどちらも同じ使い方ですが、実際には違います。

ミューテックスの場合、それをロックしたスレッドだけがそれをアンロックできます。他のスレッドがそれをロックするようになると、待機します。

セマフォンの場合、そうではありません。セマフォは特定のスレッドIDと結び付けられていません。

1
Neeraj Sh

答えはターゲットOSによって異なります。たとえば、私がよく知っている少なくとも1つのRTOS実装は、それらがすべて同じスレッドコンテキスト内からのものである限り、単一のOSミューテックスに対して複数の連続した "get"操作を許可します。別のスレッドがミューテックスを取得することを許可される前に、倍数の取得は同数の書き込みで置き換えられなければなりません。 これは、スレッドコンテキストに関係なく、一度に1つのgetしか許可されないバイナリセマフォとは異なります。

このタイプのミューテックスの背後にある考え方は、一度に1つのコンテキストでデータの変更のみを許可することでオブジェクトを保護するということです。スレッドがミューテックスを取得してからオブジェクトをさらに変更する(そしてプロテクタミューテックスを自身の操作を中心に取得/配置する)関数を呼び出したとしても、それらの操作はすべて単一のスレッドで行われるため、操作は安全です。

{
    mutexGet();  // Other threads can no longer get the mutex.

    // Make changes to the protected object.
    // ...

    objectModify();  // Also gets/puts the mutex.  Only allowed from this thread context.

    // Make more changes to the protected object.
    // ...

    mutexPut();  // Finally allows other threads to get the mutex.
}

もちろん、この機能を使用するときは、単一​​スレッド内のすべてのアクセスが本当に安全であることを確認する必要があります。

このアプローチがどれほど一般的なのか、あるいは私が慣れ親しんでいるシステムの外でそれが適用されるのかどうかはわかりません。この種のミューテックスの例については、ThreadX RTOSを参照してください。

1
Casey Barker

ここで多くの人が言及したように、ミューテックスは重要なコード(AKAクリティカルセクション)を保護するために使用されます。ミューテックスを獲得し(ロック)、クリティカルセクションに入り、ミューテックスを解除します(アンロック) すべて同じスレッド

セマフォを使用している間は、別のスレッド(スレッドBなど)がタスクを完了するまでスレッドをセマフォ(スレッドAなど)で待機させ、待機を停止するようにスレッドAのセマフォを設定してそのタスクを続行できます。

1
Dom045

基本的な問題は並行性です。複数の制御フローがあります。共有メモリを使用する2つのプロセスについて考えます。これで、一度に1つのプロセスのみが共有メモリにアクセスできます。一度に複数のプロセスが共有メモリにアクセスすると、共有メモリの内容が破損します。それは線路のようなものです。その上を走ることができる列車は1つだけです。そうしないと事故が発生します。そのため、ドライバーがチェックする信号メカニズムがあります。信号が緑の場合、列車は通行できますが、赤の場合、線路を使用するまで待つ必要があります。同様に、共有メモリの場合、バイナリセマフォがあります。セマフォが1の場合、プロセスはそれを取得し(0にし)、先に進んでアクセスします。セマフォが0の場合、プロセスは待機します。バイナリセマフォが提供しなければならない機能は相互排除(またはミューテックス)です。そのため、多数の同時実行エンティティ(プロセスまたはスレッド)の1つだけが相互に排除します。リソースの複数のインスタンスを同期するのに役立つセマフォをカウントできるのはプラスです。

相互排除は、セマフォによって提供される基本的な機能です。現在、スレッドのコンテキストでは、別の名前と構文を持っているかもしれません。しかし、基本的な概念は同じです。つまり、並行プログラミングでコードとデータの整合性を維持する方法です。私の意見では、所有権のようなもの、および関連するチェックは、実装によって提供される改良です。

0
kjohri

"バイナリセマフォ"は、"ミューテックス"のような"セマフォ"を使用することを回避するプログラミング言語です。明らかに2つの大きな違いがあります。

  1. あなたがそれらのそれぞれを呼び出す方法。

  2. 「識別子」の最大長。

0
ilias iliadis