名詞定義:
Process - 已被載入到記憶體中執行的 Program 。
應用程式 A 需要等待應用程式 B 完成動作 C 之後,才能繼續執行;換句話說,在 B 執行完 C 之前,應用程式 A 必須被 blocked(阻塞)或 paused(暫停)。
這樣的需求,在現代化的作業系統的設計中,有很多種方式可以完成,例如:signal、pipe、mutex、semaphore…等。
今天要的達成此目標, Mutex 是這些眾多方式的其中一個簡單易用的機制;透過 .NET 的 Mutex 類別 更不難實現這樣的機制。
這邊直接上兩個 .NET 程式的 C# 實作。
應用程式 A :
var mutexName = "TheMutexTest";
Console.WriteLine($"[MutexTestA] 啟動,開始找尋 MutexTestB 所建立名為 {mutexName} 的 Mutex。");
var waitCount = 0;
Mutex mutex;
while (!Mutex.TryOpenExisting(mutexName, out mutex))
{
waitCount++;
Console.WriteLine($"[MutexTestA] 尚未找到 MutexTestB 名稱為 {mutexName} 的 Mutex,會在 1 秒後重試…");
Thread.Sleep(TimeSpan.FromSeconds(1));
if (waitCount >= 30)
{
Console.WriteLine($"[MutexTestA] 已等了 {waitCount} 秒,找不到 MutexTestB 所建立名稱為 {mutexName} 的 Mutex,結束 MutexTestA");
return ;
}
}
using (mutex)
{
Console.WriteLine($"[MutexTestA] 已找到 MutexTestB 所建立名為 {mutexName} 的 Mutex。");
var acquired = false;
try
{
Console.WriteLine($"[MutexTestA] 將透過 MutexTestB 所建立名為 {mutexName} 的 mutex ,等待 MutexTestB 執行完任務 C。");
mutex.WaitOne();
acquired = true;
Console.WriteLine($"[MutexTestA] 等待完成。");
}
finally
{
if (acquired)
{
mutex.ReleaseMutex();
Console.WriteLine($"[MutexTestA] 已釋放原先 MutexTestB 所建立名為 {mutexName} 的 Mutex");
}
}
Console.WriteLine($"[MutexTestA] 來處理該處理的事情...");
Console.WriteLine($"[MutexTestA] 程式執行結束。");
}
應用程式 B:
var mutexName = "TheMutexTest";
using var mutex = new Mutex(false, mutexName, out var createdNew);
Console.WriteLine($"[MutexTestB] 啟動,等待取得 '{mutexName}'。");
Console.WriteLine($"[MutexTestB] 已{(createdNew ? "建立" : "開啟")} 名稱為 {mutexName} 的 Mutex。");
mutex.WaitOne();
try
{
Console.WriteLine($"[MutexTestB] Mutex 已鎖定,其他 Process 需等待,模擬執行重要任務 C ,執行任務 C 需要花 5 秒完成...");
Thread.Sleep(TimeSpan.FromSeconds(5));
}
finally
{
Console.WriteLine($"[MutexTestB] 工作完成,即將釋放名為 {mutexName} 的 Mutex。");
mutex.ReleaseMutex();
}
Console.WriteLine("[MutexTestB] 程式執行結束。");
先將 "應用程式 A" 執行起來後,按照應用程式 A 的應有的執行邏輯,就會透過 Mutex.TryOpenExisting的方法找尋名稱為 "TheMutexTest" 的 Mutex 存不存在目前的系統中,如果找尋 30 次每次間隔 1 秒,這 30 次都沒有尋找到就結束 "應用程式 A" 的執行;而若有尋找到的話,"應用程式 A" 就會等待 "應用程式 B" 執行完任務 C 後再繼續執行後續處理。
接著再將 "應用程式 B" 執行起來,按照應用程式 B 的應有的執行邏輯,會建立一個名為 "TheMutexTest" 的 Mutex 後,並且在開始執行任務 C 之前,透過所建立的 Mutex 鎖定後,才進行任務 C 的處理。
測試的過程如下:

在 MutexTestA 執行後才執行 MutexTestB。
並且會觀察到在 MutexTestB 開始執行後,MutexTestA 會開始等待 MutexTestB 執行完 "任務 C" 後才繼續往下執行。
不過…在 Windows 上都沒什麼問題,到了 "非 Windows 環境" 就…請看下篇。
I'm a Microsoft MVP - Developer Technologies (From 2015 ~).

I focus on the following topics: Xamarin Technology, Azure, Mobile DevOps, and Microsoft EM+S.
If you want to know more about them, welcome to my website:
https://jamestsai.tw
本部落格文章之圖片相關後製處理皆透過 Techsmith 公司 所贊助其授權使用之 "Snagit" 與 "Snagit Editor" 軟體製作。