最好自己手動敲下代碼,對理解有很大協助。
摘要
又不知是哪位前輩高人所寫:在WC裡占蹲位的3種方法:
1、如果你只對某個蹲位情有獨鐘,就要WaitOne(),但是不要忘了ReleaseMutex(),千萬別WaitOne()兩次只ReleaseMutex()一次(你幹這種佔著MK不LS的事,憋壞了後來的小朋友怎麼辦?就算沒有小朋友,憋壞了小貓小狗也不好啊……);
2、如果你喜歡講排場,需要佔2個蹲位才肯辦事,則要WaitAll([蹲位1, 蹲位2]);
3、如果你覺得隨便去哪個蹲位辦事都無所謂,那就可以WaitAny([蹲位1, 蹲位2])……。
Mutex的WaitOne()函數
前幾天1-2-3去黑木崖找東方不敗玩,聽到東方不敗抱怨說整天繡花眼睛好累呀,於是1-2-3就給東方不敗編了一個活動眼睛的程式。
class Program{ static void Main(string[] args) { // 為方便把表單設小一點 Console.WindowWidth = 30; Console.BufferWidth = 30; Console.WindowHeight = 16; Console.BufferHeight = 16; Mutex mk = new Mutex(false, "my mutex"); for (int i = 0; i < 1000; i++) { mk.WaitOne(); for (int j = 0; j < 30; j++) { Console.Write(">"); Thread.Sleep(100); } mk.ReleaseMutex(); Thread.Sleep(500); } }}
接連運行此程式的兩個執行個體(運行一個控制台應用程式後再點運行,即表示開啟兩個進程),把它們並排排放在一起(如所示),即可看到箭頭從左邊的表單“穿越”到右邊表單的效果了。
是的,我們需要同步兩個進程(中的主線程),這個工作需要交給Mutex。Mutex和Monitor的概念十分相似,只不過Monitor是.net內建的線程同步機制,Mutex是封裝了Windows作業系統的線程同步機制;Monitor速度快,Mutex的速度要比Monitor慢很多;Monitor只能用於同步同一進程內的線程;Mutex則可以用於同步隸屬於不同進程的線程。
Mutex的WaitAll()函數
現在我們對WC進行了擴建,把mk增加到兩個,可是卻遇到了兩個講排場的進程,它們都要同時佔兩個mk才肯辦事,所以運行起來的效果和前一個程式一樣。
class Program{ static void Main(string[] args) { // 為方便把表單設小一點 Console.WindowWidth = 30; Console.BufferWidth = 30; Console.WindowHeight = 16; Console.BufferHeight = 16; Mutex mk1 = new Mutex(false, "my mutex1"); Mutex mk2 = new Mutex(false, "my mutex2"); Mutex[] mks = new Mutex[] { mk1, mk2 }; for (int i = 0; i < 1000; i++) { Mutex.WaitAll(mks); for (int j = 0; j < 30; j++) { Console.Write(">"); Thread.Sleep(100); } mk1.ReleaseMutex(); mk2.ReleaseMutex(); Thread.Sleep(500); } }}
Mutex的WaitAny()函數
看下這個小程式:
class Program { static void Main(string[] args) { // 為方便把表單設小一點 Console.WindowWidth = 30; Console.BufferWidth = 30; Console.WindowHeight = 16; Console.BufferHeight = 16; Mutex mk1 = new Mutex(false, "my mutex1"); Mutex mk2 = new Mutex(false, "my mutex2"); Mutex[] mks = new Mutex[] { mk1, mk2 }; for (int i = 0; i < 1000; i++) { int index = Mutex.WaitAny(mks); // 傳回值為此進程佔用的mk在mks裡的index Console.Write("Index: " + index.ToString()); for (int j = 0; j < 30; j++) { Console.Write(">"); Thread.Sleep(100); } mks[index].ReleaseMutex(); Thread.Sleep(new Random().Next(100, 3000)); } }}
如果同時運行此程式的兩個執行個體,正如本文摘要裡所寫的,只要mk1和mk2有一個是閒置,進程就可以進去辦事,所以兩個進程可以同時輸出">"字元。注意程式的第24行,每個進程在輸出30個">"字元後都會隨機Sleep 100到3000毫秒,這樣就有可能出現mk1和mk2同時閒置情況,所以就會出現一會兒進程1佔用mk1而進程2佔用mk2;一會兒進程1佔用mk2而進程2佔用mk1的情況(在分別用綠色和紅色波浪線標出)。
參考:http://www.cnblogs.com/1-2-3/articles/1212391.html