Mutex (Mutual Exclusion) 類似「計程車」:同一時間只能有一個執行緒「搭乘」(擁有)。支援跨進程同步(具名 Mutex),功能比 lock/Monitor 強大。
| 方法 | 用途 |
|---|---|
WaitOne() | 等待擁有權,取得後進入關鍵區 |
WaitOne(timeout) | 帶逾時等待,避免無限阻塞 |
ReleaseMutex() | 釋放擁有權,喚醒下一個等待執行緒 |
WaitAll(Mutex[]) | 等待所有 Mutex 釋放(原子性) |
WaitAny(Mutex[]) | 等待任一 Mutex 釋放 |
using System;
using System.Threading;
public class MutexSample
{
static Mutex _m1, _m2;
static AutoResetEvent _e1, _e2, _e3, _e4;
const int ITERS = 100;
public static void Main()
{
Console.WriteLine("Mutex Sample ...");
_m1 = new Mutex(true, "MyMutex"); // 具名,主執行緒初始擁有
_m2 = new Mutex(true); // 無名,主執行緒初始擁有
Console.WriteLine(" - Main Owns m1 and m2");
_e1 = new AutoResetEvent(false);
_e2 = new AutoResetEvent(false);
_e3 = new AutoResetEvent(false);
_e4 = new AutoResetEvent(false);
var evs = new[] { _e1, _e2, _e3, _e4 };
var sample = new MutexSample();
var t1 = new Thread(sample.T1_Start); // WaitAll(m1, m2)
var t2 = new Thread(sample.T2_Start); // WaitOne(m1)
var t3 = new Thread(sample.T3_Start); // WaitAny(m1, m2)
var t4 = new Thread(sample.T4_Start); // WaitOne(m2)
t1.Start(); t2.Start(); t3.Start(); t4.Start();
Thread.Sleep(2000);
Console.WriteLine(" - Main releases m1");
_m1.ReleaseMutex(); // t2, t3 條件滿足
Thread.Sleep(1000);
Console.WriteLine(" - Main releases m2");
_m2.ReleaseMutex(); // t1, t4 條件滿足
WaitHandle.WaitAll(evs); // 等待四執行緒結束
Console.WriteLine("... Mutex Sample");
Console.ReadLine();
}
public void T1_Start()
{
Console.WriteLine("t1 Start: WaitAll(m1, m2)");
Mutex.WaitAll(new[] { _m1, _m2 });
Thread.Sleep(2000);
Console.WriteLine("t1 End: WaitAll satisfied");
_e1.Set();
}
public void T2_Start()
{
Console.WriteLine("t2 Start: m1.WaitOne()");
_m1.WaitOne();
Console.WriteLine("t2 End: m1.WaitOne satisfied");
_e2.Set();
}
public void T3_Start()
{
Console.WriteLine("t3 Start: WaitAny(m1, m2)");
Mutex.WaitAny(new[] { _m1, _m2 });
Console.WriteLine("t3 End: WaitAny satisfied");
_e3.Set();
}
public void T4_Start()
{
Console.WriteLine("t4 Start: m2.WaitOne()");
_m2.WaitOne();
Console.WriteLine("t4 End: m2.WaitOne satisfied");
_e4.Set();
}
}

true)WaitAll(m1, m2) → 需兩者皆釋放m1.WaitOne() → 需 m1 釋放WaitAny(m1, m2) → 需任一釋放m2.WaitOne() → 需 m2 釋放ReleaseMutex(m1) → t2、t3 解除阻塞ReleaseMutex(m2) → t1、t4 解除阻塞WaitHandle.WaitAll(evs) 等待四個 AutoResetEvent 全部觸發Set():發送訊號,釋放單一等待執行緒,自動重置為非訊號狀態WaitOne():等待訊號Reset():手動重置為非訊號ManualResetEvent:後者 Set() 釋放所有等待執行緒,需手動 Reset()| 特性 | 說明 |
|---|---|
| 跨進程同步 | 具名 Mutex 系統級可見,不同進程可共享 |
| 擁有權語意 | 只有擁有者能 ReleaseMutex,否則擲例外 |
| 遺棄 Mutex | 擁有者異常終止未釋放,下一個等待者取得並收到 AbandonedMutexException |
| 重進入 | 同一執行緒可多次 WaitOne,需對應次數 ReleaseMutex |