多線程中Mutex類用法(經典)

來源:互聯網
上載者:User

最好自己手動敲下代碼,對理解有很大協助。

摘要
  又不知是哪位前輩高人所寫:在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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.