程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#簡單多線程使用(同步和優先權)

C#簡單多線程使用(同步和優先權)

編輯:C#入門知識

一些概念了解  

阻塞:函數返回結果之前,線程被掛起

非阻塞:函數執行完立即返回,不會阻塞線程

同步:函數沒有執行完不返回,線程被掛起;

異步:函數立即返回,結果通過事件或是信號通知調用者; 

 

同步消息處理就好比linux中簡單的read/write操作,它們需要等待這操作成功才能返回;而異步處理機制就是類似於select/poll之類的多路復用IO操作,當所關注的消息被觸發時,由消息觸發機制通知觸發對消息的處理.

進程:當一個程序運行時,它就是一個進程,進程包括運行中的程序所使用到的內存和系統資源,同時一個進程可以包括多個線程

 

線程:線程是程序中的一個執行流,每個線程都有自己的專有寄存器(棧指針、程序計數器等),但代碼區是共享的,即不同的線程可以執行同樣的函數。

 

多線程:多線程是指程序中包含多個執行流,即在一個程序中可以同時運行多個不同的線程來執行不同的任務,也就是說允許單個程序創建多個並行執行的線程來完成各自的任務。時間片有CPU分配運行!

 

Thread主要方法:Strart(),Sleep(int),Abort(),Suspend(),Resume()

 

線程優先級:在C#應用程序中,用戶可以設定5個不同的優先級,由高到低分別是Highest,AboveNormal,Normal,BelowNormal,Lowest,在創建線程時如果不指定優先級,那麼系統默認為ThreadPriority.Normal。

 

線程同步(Framework中已經為我們提供了三個加鎖的機制,分別是Monitor類、Lock關鍵字和Mutex類。
):

a.C#提供了一個關鍵字lock,它可以把一段代碼定義為互斥段(critical section),互斥段在一個時刻內只允許一個線程進入執行,而其他線程必須等待。

在C#中,關鍵字lock定義如下:

lock(expression表達式) statement_block

b.Monitor主要用法

Monitor.Enter(obj);

(expression)

Monitor.Exit(obj);

c.Mutex用法

Mutex mutex = new Mutex();

mutex.WaitOne();

(expression)

mutex.ReleaseMutex();


舉個lock互斥例子(包括多線程使用和多線程優先權、同步使用):

 

[csharp] 
using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Threading; 
namespace TestThread 

    class Program 
    { 
        private static object lockObject = new object(); 
        private static object lockObject2 = new object(); 
        private static int iGetHBnum = 0; 
        private static int iPutHBnum = 0; 
        private static int count21 = 0; 
        private static int count22 = 0; 
        private static int count23 = 0; 
 
        private static int count11 = 0; 
        private static int count12 = 0; 
 
        static void Main(string[] args) 
        { 
            Console.WriteLine("主線程運行,線程ID:" + Thread.CurrentThread.ManagedThreadId.ToString()); 
 
            Thread chushi1 = new Thread(PutHB); 
            chushi1.Priority = ThreadPriority.AboveNormal; 
            chushi1.Name = "11"; 
            chushi1.Start(); 
         
            Thread chushi2 = new Thread(PutHB); 
            chushi2.Priority = ThreadPriority.Normal; 
            chushi2.Name = "12"; 
            chushi2.Start();         
      
 
            Thread Consume21 = new Thread(GetHB); 
            Consume21.Priority = ThreadPriority.Normal; 
            Consume21.Name = "21"; 
            Consume21.Start(); 
 
            Thread Consume22 = new Thread(GetHB); 
            Consume22.Priority = ThreadPriority.Normal; 
            Consume22.Name = "22"; 
            Consume22.Start(); 
 
            Thread Consume23 = new Thread(GetHB); 
            Consume23.Priority = ThreadPriority.Normal; 
            Consume23.Name = "23"; 
            Consume23.Start(); 
 
            Console.ReadKey(); 
        } 
 
        public static void PutHB() 
        { 
            string strID = Thread.CurrentThread.Name.ToString(); 
            Console.WriteLine("{0}廚師開始制作漢堡,,,", strID); 
 
            while (true) 
            { 
 
                if (iPutHBnum >= 6) 
                { 
                    Console.WriteLine("廚師{0},最多放6個漢堡,請讓銷售員取再放!", strID); 
                    Thread.Sleep(1000); 
                } 
                else 
                {      
 
                    if (iGetHBnum >= 70 ||count11 + count12 >= 70) 
                    { 
                        if (strID == "11") 
                        { 
                            Console.WriteLine("廚師{0},在貨架放共放{1}漢堡!", strID, count11); 
                        } 
                        else if (strID == "12") 
                        { 
                            Console.WriteLine("廚師{0},在貨架放共放{1}漢堡!", strID, count12); 
                        } 
                        break; 
                    } 
 
                    lock (lockObject) 
                    { 
                        iPutHBnum++; 
                        
                    } 
 
                    if (strID == "11") 
                    { 
                        count11++; 
                        Console.WriteLine("廚師{0},在貨架放已放{1}漢堡! 現在貨架有{2}漢堡!", strID,count11, iPutHBnum); 
                   
                    } 
                    else if (strID == "12") 
                    { 
                        count12++; 
                        Console.WriteLine("廚師{0},在貨架放已放{1}漢堡! 現在貨架有{2}漢堡!", strID, count12, iPutHBnum); 
               
                    } 
                } 
            } 
 
        } 
 
        public static void GetHB() 
        { 
            string strID = Thread.CurrentThread.Name.ToString(); 
            Console.WriteLine("{0}銷售員取漢堡,,,", strID); 
             
                while (true) 
                {  
                    if (iPutHBnum <= 0) 
                    { 
                        Thread.Sleep(1000); 
                        Console.WriteLine("{0}貨架台已0個漢堡,請等待廚師制作!", strID); 
                        
                    } 
                    else 
                    { 
                        lock (lockObject2) 
                        {  
                            iGetHBnum++; 
                            iPutHBnum--;    
                        } 
 
                        if (strID == "23") 
                        { 
                            count23++; 
                            Console.WriteLine("23號銷售員已銷售---{0}!", count23); 
                            Thread.Sleep(3000); 
                        } 
                        else if (strID == "22") 
                        { 
                            count22++; 
                            Console.WriteLine("22號銷售員已銷售---{0}!", count22); 
                            Thread.Sleep(2000); 
                        } 
                        else if (strID == "21") 
                        { 
                            count21++; 
                            Console.WriteLine("21號銷售員已銷售---{0}!", count21); 
                            Thread.Sleep(1000); 
                        } 
                        
                    } 
 
                    if (iGetHBnum >= 70) 
                    { 
                        Console.WriteLine("銷售完!"); 
 
                        if (strID == "23") 
                        { 
                            Console.WriteLine("23號銷售員銷售總數:{0}", count23); 
                        } 
                        else if (strID == "22") 
                        { 
                            Console.WriteLine("22號銷售員銷售總數:{0}", count22); 
                        } 
                        else if (strID == "21") 
                        { 
                            Console.WriteLine("21號銷售員銷售總數:{0}", count21); 
                        } 
                        break; 
                    } 
 
 
                } 
             
 
 
        } 
    } 

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace TestThread
{
    class Program
    {
        private static object lockObject = new object();
        private static object lockObject2 = new object();
        private static int iGetHBnum = 0;
        private static int iPutHBnum = 0;
        private static int count21 = 0;
        private static int count22 = 0;
        private static int count23 = 0;

        private static int count11 = 0;
        private static int count12 = 0;

        static void Main(string[] args)
        {
            Console.WriteLine("主線程運行,線程ID:" + Thread.CurrentThread.ManagedThreadId.ToString());

            Thread chushi1 = new Thread(PutHB);
            chushi1.Priority = ThreadPriority.AboveNormal;
            chushi1.Name = "11";
            chushi1.Start();
       
            Thread chushi2 = new Thread(PutHB);
            chushi2.Priority = ThreadPriority.Normal;
            chushi2.Name = "12";
            chushi2.Start();       
    

            Thread Consume21 = new Thread(GetHB);
            Consume21.Priority = ThreadPriority.Normal;
            Consume21.Name = "21";
            Consume21.Start();

            Thread Consume22 = new Thread(GetHB);
            Consume22.Priority = ThreadPriority.Normal;
            Consume22.Name = "22";
            Consume22.Start();

            Thread Consume23 = new Thread(GetHB);
            Consume23.Priority = ThreadPriority.Normal;
            Consume23.Name = "23";
            Consume23.Start();

            Console.ReadKey();
        }

        public static void PutHB()
        {
            string strID = Thread.CurrentThread.Name.ToString();
            Console.WriteLine("{0}廚師開始制作漢堡,,,", strID);

            while (true)
            {

                if (iPutHBnum >= 6)
                {
                    Console.WriteLine("廚師{0},最多放6個漢堡,請讓銷售員取再放!", strID);
                    Thread.Sleep(1000);
                }
                else
                {    

                    if (iGetHBnum >= 70 ||count11 + count12 >= 70)
                    {
                        if (strID == "11")
                        {
                            Console.WriteLine("廚師{0},在貨架放共放{1}漢堡!", strID, count11);
                        }
                        else if (strID == "12")
                        {
                            Console.WriteLine("廚師{0},在貨架放共放{1}漢堡!", strID, count12);
                        }
                        break;
                    }

                    lock (lockObject)
                    {
                        iPutHBnum++;
                      
                    }

                    if (strID == "11")
                    {
                        count11++;
                        Console.WriteLine("廚師{0},在貨架放已放{1}漢堡! 現在貨架有{2}漢堡!", strID,count11, iPutHBnum);
                 
                    }
                    else if (strID == "12")
                    {
                        count12++;
                        Console.WriteLine("廚師{0},在貨架放已放{1}漢堡! 現在貨架有{2}漢堡!", strID, count12, iPutHBnum);
             
                    }
                }
            }

        }

        public static void GetHB()
        {
            string strID = Thread.CurrentThread.Name.ToString();
            Console.WriteLine("{0}銷售員取漢堡,,,", strID);
           
                while (true)
                {
                    if (iPutHBnum <= 0)
                    {
                        Thread.Sleep(1000);
                        Console.WriteLine("{0}貨架台已0個漢堡,請等待廚師制作!", strID);
                      
                    }
                    else
                    {
                        lock (lockObject2)
                        {
                            iGetHBnum++;
                            iPutHBnum--;  
                        }

                        if (strID == "23")
                        {
                            count23++;
                            Console.WriteLine("23號銷售員已銷售---{0}!", count23);
                            Thread.Sleep(3000);
                        }
                        else if (strID == "22")
                        {
                            count22++;
                            Console.WriteLine("22號銷售員已銷售---{0}!", count22);
                            Thread.Sleep(2000);
                        }
                        else if (strID == "21")
                        {
                            count21++;
                            Console.WriteLine("21號銷售員已銷售---{0}!", count21);
                            Thread.Sleep(1000);
                        }
                      
                    }

                    if (iGetHBnum >= 70)
                    {
                        Console.WriteLine("銷售完!");

                        if (strID == "23")
                        {
                            Console.WriteLine("23號銷售員銷售總數:{0}", count23);
                        }
                        else if (strID == "22")
                        {
                            Console.WriteLine("22號銷售員銷售總數:{0}", count22);
                        }
                        else if (strID == "21")
                        {
                            Console.WriteLine("21號銷售員銷售總數:{0}", count21);
                        }
                        break;
                    }


                }
           


        }
    }
}

結果:

 \


lock可以用Monitor,Mutex替代

 
                    Monitor.Enter(lockObject);
                  
                        iPutHBnum++;
                      
                    Monitor.Exit(lockObject);

或者

                    mutex1.WaitOne(); 

                
                        iPutHBnum++;


                    mutex1.ReleaseMutex();

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved