2つ(またはそれ以上)のスレッドが同時にロックを取得することはできません。たとえば、いくつかのタイプの同期方法があります。
アクティブ待機-スピンロック
擬似コード:
1. while ( xchg(lock, 1) == 1); - entry protocole
XCHGは、最初に「ロック」変数に新しい値を設定してから古い値を返すアトミック操作(x86アーキテクチャ上に存在する)の例です。アトミックとは、割り込みできないことを意味します-上記の例では、新しい値を設定してから古い値を返すまでの間です。アトミック-何があっても決定的な結果。
2. Your code
3. lock = 0; - exit protocol
ロックが0に等しい場合、別のスレッドがクリティカルセクションに入り、ループが終了します。
スレッドの中断-たとえば、セマフォのカウント
アトミック操作が2つ.Wait()
あり.Signal()
、整数変数を呼び出すことができますint currentValue
。
Wait():
if (currentValue > 0) currentValue -= 1;
else suspend current thread;
Signal():
If there exists thread suspended by semaphore wake up one of them
Else currentValue += 1;
クリティカルセクションの問題の解決は本当に簡単です。
擬似コード:
mySemaphore.Wait();
do some operations - critical section
mySemaphore.Signal();
通常、プログラミングスレッドAPIを使用すると、セマフォクリティカルセクションで最大同時スレッドを指定できます。明らかに、マルチスレッドシステムにはより多くの種類の同期(ミューテックス、モニター、バイナリセマフォなど)がありますが、それらは上記のアイデアに基づいています。スレッドのサスペンドを使用するメソッドは、アクティブな待機よりも優先されるべきであると主張することができます(CPUは無駄になりません)-常に真実とは限りません。スレッドが中断されている場合-コンテキストスイッチと呼ばれる高価な操作が実行されます。ただし、待機時間が短い場合(スレッドの数〜コアの数)が妥当です。