1

「Mutex クラスはスレッド ID を強制するため、ミューテックスはそれを取得したスレッドによってのみ解放できます。対照的に、Semaphore クラスはスレッド ID を強制しません。」

これは、MSDNの説明に記載されている内容です。しかし、私の質問Application exception is throwによると、取得していない場合でもミューテックスを解放しようとしました。次のスレッドが実行されたときに例外が表示されました。ミューテックスにアクセスできないスレッドがそれを解放したということですか??? 誰かがこの概念を理解するのを手伝ってくれませんか。何か間違っていたら教えてください。

4

2 に答える 2

1

ドキュメントに記載されているように、ミューテックスを所有していないスレッドがミューテックスを解放しようとしたため、ApplicationExceptionがスローされました。これは、ミューテックスがリリースされたことを意味するのではなく、ミューテックスをリリースしようとしたスレッドがミューテックスを所有していなかったことを意味します。

var mutex = new Mutex();
mutex.WaitOne();
var thread = new Thread(() =>
    {
       try
       {
          mutex.ReleaseMutex(); //This will throw ApplicationException
       }
       catch (ApplicationException ex)
       {
           Console.WriteLine("Failed to release mutex");
       }
    });

thread.Start();
thread.Join();

mutex.ReleaseMutex(); //No exception will be thrown here

この例では、最初のスレッドがミューテックスを作成して取得します。2番目のスレッドがスピンアップし、解放しようとして失敗します。失敗した後、所有しているスレッドはそれを解放します。

アップデート

前の質問では、そのコードを複数のスレッドで実行していること、および各スレッドに同じ競合状態が存在することに注意することが重要です。1つのスレッドがミューテックスを保持している間に、複数のスレッドがミューテックスの取得に失敗した可能性があるため、複数のスレッドも同様にミューテックスの解放に失敗します。例として、次の実行パスを取り上げます。

  • スレッド1はミューテックスを取得します。
  • スレッド1がミューテックスを持っているため、スレッド2はミューテックスの取得に失敗します。
  • スレッド1がミューテックスを持っているため、スレッド3はミューテックスの取得に失敗します。
  • スレッド3はミューテックスを解放しようとし、ミューテックスを所有していないため、ApplicationExceptionをスローします。
  • スレッド1はミューテックスを解放します。
  • スレッド2はミューテックスを解放しようとし、ミューテックスを所有していないため、ApplicationExceptionをスローします。

ミューテックスの解放に失敗したときにスレッド3が爆発したという事実は、スレッド2も同じことを実行して爆発したという事実とは相関関係がありません。

于 2012-05-01T19:43:27.860 に答える
0

ミューテックスの概念に関しては、それを引き出しとして想像することができ、ミューテックスを所有するスレッドはその引き出しの鍵を保持する人として想像できます。ドロワーの鍵を持っている人だけがロックを解除できるため、ミューテックスを取得したスレッドだけがそれを解放できます。

ミューテックスを所有していないスレッドからミューテックスを解放しようとすると、誰かが偽の鍵で他人の引き出しを開こうとするようなものなので、泥棒を捕まえるために例外がスローされます!

ミューテックスが行うのはそれだけで、複数のスレッドが「保護されたコード」を実行するのを防ぎます (ドロワー内)。その名前は、一度に 1 つのスレッドを意味する「相互排除」に由来します。

于 2012-05-01T19:58:58.607 に答える