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

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

編輯:C#入門知識

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


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

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

Semaphore sema = new Semaphore(x,y)

有一隊人排隊上洗手間,人就相當於線程,x為還剩余的位置數量,y為總的位置數量。

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

請看下面例子:

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();
        }
    }

運行結果如下:

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()還有兩個重載方法不是很常用這裡就不介紹了。上面的重載方法這裡也不再進了案例說明了,有興趣的朋友可以自己嘗試一下。

作者:依封劍白
出處:C#多線程--信號量(Semaphore)
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。如有問題或建議,請多多賜教,非常感謝。

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