c#中的多線程同步

來源:互聯網
上載者:User

       在處理多線程同步問題的時候,我們一般有臨界區,互斥量,訊號量和訊息機制等幾種解決方案,在c#中可以非常方便的使用它們來實現進程的同步。下面我就常用的lock,Monitor和Mutex幾種來說明如何?進程的同步。

    lock和Monitor依靠一種“令牌”對象來實現進程的同步,下面看一段示範代碼:

 

   class Example
    {
        int count = 0;
        object o = new object();//令牌對象
        static void Main(string[] args)
        {
            Example e=new Example();
            Thread pthread = new Thread(e.produce);
            Thread cthread = new Thread(e.consume);

            pthread.Start();

            cthread.Start();

        }
        public void produce()
        {
            while (true)
            {
                lock (o)
                {
                    count = count + 1;
                }
            }
        }
        public void consume()
        {
            while (true)
            {
                lock (o)
                {
                    count = count - 1;
                }
            }
        }
    }

        在程式中,我們需要產生兩個生產和消費的線程,但是兩個線程對count的訪問必須是互斥的,也就是要實現兩個現場的同步。在上面的代碼中,首先執行個體化一個令牌對象o,當需要操作互斥變數count的時候,我就用lock關鍵字去取令牌,如果此時令牌可以拿到,就執行對count的操作,然後釋放令牌。如果此時令牌在另外一個線程手裡,就等待知道該令牌被釋放。Monitor的使用與lock很相似,下面附上使用代碼,不再另加說明:

      Monitor.Enter(o);

      count=count+1;

      Monitor.Exit(o);

        Mutex是使用互斥的機制來實現進程的同步,Mutex不需要使用額外的令牌對象。下面是用Mutex來解決著名的生產者消費者問題,設定消費者和生產者各3個,公用區容量為5,生產100個,下面看代碼:

         class Program
    {
        static void Main(string[] args)
        {
            ProduceAndConsume pac=new ProduceAndConsume();
            Thread pthread1 = new Thread(pac.produce);
            Thread pthread2 = new Thread(pac.produce);
            Thread pthread3 = new Thread(pac.produce);
            Thread cthread1 = new Thread(pac.consume);
            Thread cthread2 = new Thread(pac.consume);
            Thread cthread3 = new Thread(pac.consume);
            pthread1.Start();
            pthread2.Start();
            pthread3.Start();
            cthread1.Start();
            cthread2.Start();
            cthread3.Start();
        }
    }
    class ProduceAndConsume
    {
        private int count = 0;
        private int pID=0;
        private int cID = 0;
        private object mutexobjext = new object();
        private Mutex IDmux = new Mutex();//該互斥量是對產品序號的互斥
        private Mutex Countmux = new Mutex();//該互斥量是對公用區產品數量的互斥
        public void produce()
        {
            while (true)
            {
                IDmux.WaitOne();//申請產品序號互斥,不行則等待
                if (pID >= 100)
                {

                    //達到一百個,釋放互斥,線程結束
                    IDmux.ReleaseMutex();
                    break;
                }
                Countmux.WaitOne();//申請公用區數量互斥
                if (count >= 5)
                {

                    //公用區滿,生產線程釋放互斥後睡眠
                    Countmux.ReleaseMutex();
                    IDmux.ReleaseMutex();
                    Thread.Sleep(2);
                    continue;
                }
                else
                {

                       //公用區數量加一,並列印生產產品的序號資訊,完成後釋放互斥
                        count = count + 1;
                        Countmux.ReleaseMutex();
                        pID = pID + 1;
                        Console.WriteLine("Has produced {0}..", pID);
                        IDmux.ReleaseMutex();
                        Thread.Sleep(1);
                }
            }
        }
        public void consume()
        {

            //類似於produce(),不同是消費過程
            while (true)
            {
                IDmux.WaitOne();
                if(cID>=100)
                {
                    IDmux.ReleaseMutex();
                    break;
                }
                Countmux.WaitOne();
                if (count <= 0)
                {
                    Countmux.ReleaseMutex();
                    IDmux.ReleaseMutex();
                    Thread.Sleep(2);
                    continue;
                }
                else
                {
                        count = count - 1;
                        Countmux.ReleaseMutex();
                        cID = cID + 1;
                        Console.WriteLine("Has Consume {0}", cID);
                        IDmux.ReleaseMutex();
                        Thread.Sleep(1);
                }
            }
        }
    }

      下面是執行結果,可以看到進程已經很好的同步了 :

Has produced 1..
Has produced 2..
Has produced 3..
Has produced 4..
Has produced 5..
Has Consume 1
Has produced 6..
Has Consume 2
Has Consume 3
Has Consume 4
Has produced 7..
Has Consume 5
Has Consume 6
Has produced 8..
Has produced 9..
Has Consume 7
Has produced 10..
Has Consume 8
Has Consume 9
Has Consume 10
Has produced 11..
Has produced 12..
Has Consume 11
Has produced 13..
Has produced 14..
Has produced 15..
Has Consume 12
Has produced 16..
Has Consume 13
Has Consume 14
Has produced 17..
Has produced 18..
Has Consume 15
Has produced 19..
Has Consume 16
Has produced 20..
Has Consume 17
Has produced 21..
Has produced 22..
Has Consume 18
Has Consume 19
Has Consume 20
Has produced 23..
Has Consume 21
Has Consume 22
Has produced 24..
Has Consume 23
Has produced 25..
Has produced 26..
Has Consume 24
Has produced 27..
Has Consume 25
Has Consume 26
Has produced 28..
Has Consume 27
Has Consume 28
Has produced 29..
Has produced 30..
Has Consume 29
Has produced 31..
Has Consume 30
Has Consume 31
Has produced 32..
Has Consume 32
Has produced 33..
Has produced 34..
Has produced 35..
..................................

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.