C#多線程--信號量(Semaphore)

若是須要查看更多文章,請微信搜索公衆號 csharp編程大全,須要進C#交流羣羣請加微信z438679770,備註進羣, 我邀請你進羣! ! !html

emaphore:可理解爲容許線程執行信號的池子,池子中放入多少個信號就容許多少線程同時執行。編程

本文連接:微信

https://www.cnblogs.com/yifengjianbai/p/5468449.html併發

百度百科:Semaphore,是負責協調各個線程, 以保證它們可以正確、合理的使用公共資源。也是操做系統中用於控制進程同步互斥的量。操作系統

Semaphore經常使用的方法有兩個WaitOne()Release(),Release()的做用是退出信號量並返回前一個計數,而WaitOne()則是阻止當前線程,直到當前線程的WaitHandle 收到信號。這裏我舉一個例子讓你們更容易理解:當咱們這樣實例化Semaphore時候線程

 

Semaphore sema = new Semaphore(x,y)

有一隊人排隊上洗手間,人就至關於線程,x爲還剩餘的位置數量,y爲總的位置數量。3d

WaitOne()方法就至關於人在等待洗手間位置的行爲,而Release()方法就至關於一我的從洗手間出來的行爲,這裏再假設x和y都爲5,說明開始的時候洗手間有5個空位置,且總共只有5個位置,當一隊超過5我的的隊伍要上洗手間的就排隊,首先WaitOne()方法等待,發現有空位就依次進去,每進去一個空位減一,直到進去5以後個沒有空位,這時候後面的人就一直等待,直到進去的人從洗手間出來Release()方法,空位加一,在等待WaitOne()方法的人發現有空位又進去一個空位減一……如此循環往復。orm

請看下面例子:htm

public class Program
    {
        static Semaphore sema = new Semaphore(5, 5);
        const int cycleNum = 9;
        static void Main(string[] args) 
        {
            for(int i = 0; i < cycleNum; i++)
            {
                Thread td = new Thread(new ParameterizedThreadStart(testFun));
                td.Name = string.Format("編號{0}",i.ToString());
                td.Start(td.Name);
            }
            Console.ReadKey();
        }
        public static void testFun(object obj)
        {
            sema.WaitOne();
            Console.WriteLine(obj.ToString() + "進洗手間:" + DateTime.Now.ToString());
            Thread.Sleep(2000);
            Console.WriteLine(obj.ToString() + "出洗手間:" + DateTime.Now.ToString());
            sema.Release();
        }
    }
複製代碼

  

 

 

這裏我要說明一點,信號量控制的只是線程同步的量,而無論順序,這個例子來講線程控制的就是線程同步量爲5,也就是同時併發的線程數量爲5個,至因而哪一個先哪一個後不是由這裏的信號量決定的。blog

固然這個例子中因沒有作什麼複雜的操做,通常狀況進入線程的時間和每一個線程要的時間不會有太大差異,因此執行的順序仍是很規律的(爲了說明這個問題我也是運行了屢次才讓結果稍有不一樣,這裏編號2搶在了編號1前面就是這個道理),若是線程中有很複雜的操做每一個線程在運行中所用的時間有比較大的差異,或者循環開始有複雜操做那麼極可能就不是編號0先進入洗手間了,且不必定是先進入的就會先出來。

接下來再簡單介紹一下Semaphore的WaitOne()和Release()的重載方法

public int Release(int releaseCount);

releaseCount指的是釋放的信號量數量,若是沒有參數默認爲1,Release()就至關於Release(1)

這裏要說明一點,當Release()或者Release(int releaseCount)執行時致使信號量計數大於最大數量時會拋出SemaphoreFullException異常。下面這種狀況就會異常:

Semaphore sem = new Semaphore(4,5);
sem.Release(2);//這裏是釋放2個信號量加上以前的4個,超出5個了

 

public virtual bool WaitOne(TimeSpan timeout);
public virtual bool WaitOne(int millisecondsTimeout);

第一個重載參數timeout:指定時間間隔,若在這段時間內沒有接收到信號則跳過等待繼續執行

第二個重載參數millisecondsTimeout:指定時間間隔整數毫秒,若在這段時間內沒有接收到信號則跳過等待繼續執行

WaitOne()還有兩個重載方法不是很經常使用這裏就不介紹了。上面的重載方法這裏也再也不進了案例說明了,有興趣的朋友能夠本身嘗試一下。

說明:

一、若是semaphore.Release(n),n>semaphore最大容納信號量,將出異常。二、當semaphore擁有的信號量爲1時,Semaphore至關於Mutex三、當semaphore擁有的信號量>1時,信號量的數量便可供多個線程同時獲取的個數,此時可認爲獲取到信號量的線程將同時執行(實際狀況可能與CPU核心數、CPU同時支出線程數有關)

相關文章
相關標籤/搜索