2012-08-02 22 views
16

mutexの背後にあるアイデアは、ある時点でメモリのセクションにアクセスするスレッドを1つだけ許可することです。あるスレッドがmutexをロックすると、最初のロックが解除されるまで他のロックの試みはブロックされます。ただし、これはどのように実装されていますか?自分自身をロックするには、ミューテックスはロックされているというビットをどこかに設定する必要があります。しかし、最初の文章が書かれているのと同時に2番目のミューテックスが読んでいたらどうでしょうか?さらに悪いことに、mutexを同時にロックするとどうなりますか?ミューテックスは、それが防止しようとしているのと同じ問題に陥るでしょう。どのようにミューテックスが実際に機能しますか?

ミューテックスは実際にどのように機能しますか?

答えて

10

低レベルのアトミック操作。これらは基本的にハードウェアで実装されたミューテックスです。ただし、非常に少数の操作しかアトミックに実行できません。

は、次の同等の擬似コードを考えてみましょう:

mutex global_mutex; 
void InterlockedAdd(int& dest, int value) { 
    scoped_lock lock(mutex); 
    dest += value; 
} 
int InterlockedRead(int& src) { 
    scoped_lock lock(mutex); 
    return src; 
} 
void InterlockedWrite(int& dest, int value) { 
    scoped_lock lock(mutex); 
    dest = value; 
} 

これらの機能は、CPUによって命令として実装され、彼らは様々な程度に、スレッド間の一貫性を保証しています。正確なセマンティクスは問題のCPUに依存します。 x86は逐次整合性を提供します。これは、オペレーションがある順序で連続して発行されたかのように動作することを意味します。これは明らかに少しをブロックすることを含む。

あなたは、アトミック操作がmutexの観点から実装できること、またはその逆を正確に推測することができます。しかし、通常、アトミックオペレーションはハードウェアによって提供され、次にミューテックスやその他の同期プリミティブがオペレーティングシステムによって実装されます。これは、完全なミューテックスを必要とせず、「ロックレス」として知られているものを操作できるアルゴリズムがいくつか存在するためです。つまり、スレッド間の一貫性のためにアトミック操作を使用するだけです。

9

これまで使用されてきた簡単な実装は、CPUレベルのアトミックな「ロックと交換」命令を使用することです。これは、特定の値をあるメモリ位置の値でアトミックにスワップする特別な命令です。

スレッドは、1の値をメモリ位置にスワップしようとすることによって、そのようなミューテックスを取得することができました。値が0に戻った場合、スレッドはmutexを持っているとみなして処理を続行します。それ以外の場合、返される値が1の場合、スレッドは、の他のスレッドが現在mutexを持っていることを認識します。その場合、再度試みるまで待つでしょう。

上記は、単純なシステムで起こり得ることの非常に単純化された概要です。最近のオペレーティングシステムはますます複雑になっています。

+0

これは質問に答えません。 2つのスレッドが同時に「読み込みとスワップ」を行う場合はどうでしょうか?そして、両方とも戻ります。 – user1146657

+1

@ user1146657: "ロックと交換"操作のポイントは、*アトミック*であり、CPUは常に1つのスレッドだけがそれを実行できることを保証します。定義上、2つのスレッド*は同時にそれを行うことはできません。 CPUは、この目的のためにそのように動作するように特別に設計されています。 –

1

あなたが必要とするのは、原子的に行うことだけです。これは、アトミック比較交換命令などのハードウェア、またはシステムコールを介してオペレーティングシステムによって提供されます。 OSドメインに入ったら、単一のスレッドだけがmutexをロックしようとしていることを確認するのはかなり簡単です。

実際には両方のアプローチが組み合わされます。たとえば、Linuxのfutexを参照してください。

2

はここでミューテックスが動作するために必要なものの概要ですが、それがロックされた状態を表し、メモリ内の整数値1または0で、ある私の完全な記事How does a mutex work?

  • の短縮形です。
  • mutexは、アトムcompare_and_swapを必要とします。これは、アトミックにその値を変更し、それが成功したかどうかを報告することができます。これにより、スレッドは同時に状態をチェックして変更することができます。
  • OSは、mutexがロックされている場合に待機する機能を提供する必要があります。 Linuxでは、低レベル関数はfutexです。これにより、スレッドがキューに置かれ、メモリ内の整数も監視されます。
  • 関連する操作には、ロックの前にメモリの変更が表示されず、ロック後に完全に使用できるようにするためのデータフェンスも含まれます。
関連する問題