C でのマルチスレッド プログラミングを理解しようとしています。
スレッドの同期に MUTEXES を使用しているため、ブール変数を使用してコードの重要な領域の実行をブロックできないのはなぜでしょうか。
ブール変数に対するミュートの専門は何ですか?
PS: 実はこの質問はインタビューで聞かれました。だから、これについてあなたの知識を共有してください。
C でのマルチスレッド プログラミングを理解しようとしています。
スレッドの同期に MUTEXES を使用しているため、ブール変数を使用してコードの重要な領域の実行をブロックできないのはなぜでしょうか。
ブール変数に対するミュートの専門は何ですか?
PS: 実はこの質問はインタビューで聞かれました。だから、これについてあなたの知識を共有してください。
問題は、2 つのスレッドが両方ともブール値を同時に使用できると見なす可能性があり、両方とも続行しても安全であると想定することです。
たとえば、次のコードがあるとします。
bool myLock = false; // visible to all threads
void someFunction()
{
if (!myLock)
{
myLock = true;
// do whatever
// and then release the lock
mylock = false;
}
}
ここで、2 つのスレッドが実行されているとします。スレッド AmyLock
は、それが であることを読み取って確認false
するため、次の命令に進みます。同時に、スレッド A がまだ に設定していないため、スレッド B は を読み取りmyLock
、それが であることを確認します。そのため、スレッド B もすぐに進み、ロックも取得します。この時点で、両方のスレッドが、相互排他ロックによって保護されるはずのコードを実行しています。false
true
スレッド A が実行中の処理を終了し、スレッド B がまだ実行中の状態mylock
に戻るため、事態はさらに悪化します。false
そのため、スレッド B がまだそこにある場合でも、別のスレッドが来てロックを取得できます。
ミューテックスは原子性を保証します。つまり、一度に 1 つのスレッドだけがチェックと更新を実行できることが保証されます。したがって、ブール値をミューテックスに置き換えると、次のようになります。
if (mutex.Acquire())
{
// do stuff
// then release the lock
mutex.Release();
}
2 つのスレッドがミューテックスを同時に取得できる可能性はありません。
ブール値を「偽のミューテックス」として使用しようとした場合、基本的にミューテックスを再発明するまで、実装の欠陥を簡単に指摘し続けることができます。ミューテックスは基本的に、スレッド同期に使用するために必要なすべての追加要素を備えたブール値です。