C# 多線程系列之Mutex使用
舉MSDN上的例子說明:
復制代碼
using System;
using System.Threading;
class Example
{
// Create a new Mutex. The creating thread does not own the mutex.
private static Mutex mut = new Mutex();
private const int numIterations = 1;
private const int numThreads = 3;
static void Main()
{
// Create the threads that will use the protected resource.
for(int i = 0; i < numThreads; i++)
{
Thread newThread = new Thread(new ThreadStart(ThreadProc));
newThread.Name = String.Format("Thread{0}", i + 1);
newThread.Start();
}
// The main thread exits, but the application continues to
// run until all foreground threads have exited.
}
private static void ThreadProc()
{
for(int i = 0; i < numIterations; i++)
{
UseResource();
}
}
// This method represents a resource that must be synchronized
// so that only one thread at a time can enter.
private static void UseResource()
{
// Wait until it is safe to enter, and do not enter if the request times out.
Console.WriteLine("{0} is requesting the mutex", Thread.CurrentThread.Name);
if (mut.WaitOne(1000)) {
Console.WriteLine("{0} has entered the protected area",
Thread.CurrentThread.Name);
// Place code to access non-reentrant resources here.
// Simulate some work.
Thread.Sleep(5000);
Console.WriteLine("{0} is leaving the protected area",
Thread.CurrentThread.Name);
// Release the Mutex.
mut.ReleaseMutex();
Console.WriteLine("{0} has released the mutex",
Thread.CurrentThread.Name);
}
else {
Console.WriteLine("{0} will not acquire the mutex",
Thread.CurrentThread.Name);
}
}
}
// The example displays output like the following:
// Thread1 is requesting the mutex
// Thread1 has entered the protected area
// Thread2 is requesting the mutex
// Thread3 is requesting the mutex
// Thread2 will not acquire the mutex
// Thread3 will not acquire the mutex
// Thread1 is leaving the protected area
// Thread1 has released the mutex
復制代碼
當一個線程占有Mutex後,代碼就可以這樣寫:
mutex.WaitOne();
mutex.WaitOne();
mutex.WaitOne();
mutex.WaitOne();
。。
。。
WaitOne這個方法被調用時 系統檢查發現mutex沒有被任何線程使用 故而將mutex分配給當前線程
因而就算繼續調用WaitOne也沒有影響 因為系統發現當前線程已經占有 就直接返回了。換言之,waitOne是獲取
Mutex鎖的方式。如果調用ReleaseMutex那麼當前線程退出Mutex鎖,其它線程便可進來申請。但是如果調用兩次
ReleaseMutex 那麼由於當前線程實際上是不占有鎖的 那麼會拋出異常。
所以不能這樣寫:
mutex.ReleaseMutex();//如果已經占有 那麼OK
mutex.ReleaseMutex();//調用第二次直接異常
Mutex是一個內核對象,所以,它是可以用作跨進程線程同步的。
A進程可以如此寫:
Mutex mutex = new Mutex(true,"mutex1");
B進程則可以如此寫:
Mutex mutex = Mutex.OpenExisting("mutex1")
OpenExisting這個方法簽名我們後面也可以經常看到,作用就是獲取一個已經存在的內核對象。
獲取到之後的線程同步代碼是跟單進程是一致的。
完畢。