线程、同步与锁——Mutex想说爱你不容易
還是先舉一個簡單的例子,來說明一下這個東西:
?
???public?class?ThreadMutex????{
????????public?void?Test()
????????{
????????????Thread?t1?=?new?Thread(Thread1);
????????????Thread?t2?=?new?Thread(Thread2);
????????????t1.Start();
????????????t2.Start();
????????}
????????public?void?Thread1()
????????{
????????????Mutex?m?=?new?Mutex(false,?"test");
????????????bool?b2?=?m.WaitOne();
????????????Console.WriteLine("Thread1?get?the?mutex?:?"?+?b2);
????????????Thread.Sleep(10000);
????????????m.ReleaseMutex();
????????}
????????public?void?Thread2()
????????{
????????????Mutex?m?=?new?Mutex(false,?"test");
????????????bool?b2?=?m.WaitOne();
????????????Console.WriteLine("Thread2?get?the?mutex?:?"?+?b2);
????????????Thread.Sleep(1000);
????????????m.ReleaseMutex();
????????????
????????}
}
恩,Thread1中Mutex.WaitOne()后,就想到與Thread1拿到了Mutex所有權,這時Thread2得到了同樣的Mutex,然后Mutex.WaitOne(),也想拿到Mutex的所有權,這時就必須等待了。這里只需要兩點就能明白什么是Mutex了:
1.?? Mutex是一個令牌,當一個線程拿到這個令牌時運行,另外想拿到令牌的線程就必須等待,直到拿到令牌的線程釋放令牌。沒有所有權的線程是無法釋放令牌的。
2.?? Mutex(false,”string”)中的string是令牌的關鍵,或者可以叫令牌名,因為Mutex是跨進程的,整個系統中只會有唯一的令牌存在所以,也就是說你在一個應用程序中的一個線程中得到了Mutex的所有權,那在另外一個線程中的另外的線程想得到他就必須要等待。
要弄清楚Mutex就還需要弄清楚兩個很重要的問題:
1.那就是Mutex是調用的Win32 的API?
HANDLE CreateMutex(
?? LPSECURITY_ATTRIBUTES lpMutexAttributes,
?? BOOL bInitialOwner,
?? LPCTSTR lpName
);
這就是他為什么能跨進程訪問的原因,正是由于它使用P/Invoke,他的效率問題就凸現出來,明顯不如Monitor之類的快,用的時候還需多多斟酌。
?
下面放一個Mutex的簡單實現,看看Mutex在.net下是如何實現的。
?2.Mutex的生命周期,這個問題讓我郁悶了很久,因為不太了解Mutex的機制,使得我也沒法弄清楚到底能活多長時間,這也是AbandonedMutexException經常會出現的原因。還是先來看一段程序:
?
??public?class?ThreadMutex????{
????????public?void?Test()
????????{
????????????Thread?t1?=?new?Thread(Thread1);
????????????Thread?t2?=?new?Thread(Thread2);
????????????t1.Start();
????????????t2.Start();
????????}
????????public?void?Thread1()
????????{
????????????Mutex?m?=?new?Mutex(false,?"test");
????????????bool?b2?=?m.WaitOne();
????????????Console.WriteLine("Thread1?get?the?mutex?:?"?+?b2);
????????}
????????public?void?Thread2()
????????{
????????????Thread.Sleep(10);//保證Thread1執行完
????????????Mutex?m?=?new?Mutex(false,?"test");
????????????bool?b2=m.WaitOne();
????????????Console.WriteLine(b2);
????????????m.ReleaseMutex();
????????}
}
在Thread2中的WaitOne()方法就會報錯了,AbandonedMutexException,原因就是Thread1拿到了Mutex后沒有釋放,Thread1就結束了,這樣Mutex成了被拋棄的地孩子了,呵呵。但是如果垃圾收集了,就不一樣咯。代碼稍微修改了一下:
?
??public?class?ThreadMutex????{
????????public?void?Test()
????????{
????????????Thread?t1?=?new?Thread(Thread1);
????????????Thread?t2?=?new?Thread(Thread2);
????????????t1.Start();
????????????t2.Start();
????????}
????????public?void?Thread1()
????????{
????????????Mutex?m?=?new?Mutex(false,?"test");
????????????bool?b2?=?m.WaitOne();
????????????Console.WriteLine("Thread1?get?the?mutex?:?"?+?b2);
????????}
????????public?void?Thread2()
????????{
????????????Thread.Sleep(10);//保證Thread1執行完
????????????GC.Collect();
????????????GC.WaitForPendingFinalizers();
????????????bool?b1;
????????????Mutex?m?=?new?Mutex(false,?"test",out?b1);
????????????Console.WriteLine(b1);
????????????bool?b2=m.WaitOne();
????????????Console.WriteLine(b2);
????????????m.ReleaseMutex();
????????????
????????}
????}
結果是:
Thread1 get the mutex : True
True
True
Thread2里面的Mutex是新創建的,呵呵,這里面的玄妙自己體會吧。
?
最后要說一下的是Mutex的訪問和window訪問文件的機制基本上是一樣的,window訪問對象和訪問文件使用的是同樣的安全機制(雖然我還沒看懂)。總結
以上是生活随笔為你收集整理的线程、同步与锁——Mutex想说爱你不容易的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 将iphone中的照片同步到电脑
- 下一篇: 网线有问题?