其實.NET中的信號量(Semaphore)是操作系統維持的一個整數。當整數位0時。其他線程無法進入。當整數大於0時,線程可以進入。每當一個線程進入,整數-1,線程退出后整數+1。整數不能超過信號量的最大請求數。信號量在初始化的時候可以指定這個整數的初始值。
System.Threading.Semaphore類的構造函數的兩個參數第一個就是信號量的內部整數初始值,也就是初始請求數,第二個參數就是最大請求數。
代碼
static Semaphore semaphore; //當前信號量中線程數量 static int count; //用於生成隨機數 static Random r; static void Main() { r = new Random(); //初始化信號量:初始請求數為1,最大請求數為3 semaphore = new Semaphore(1, 3); //放出10個線程 for (int i = 0; i < 5; i++) ThreadPool.QueueUserWorkItem(doo, i + 1); Console.ReadKey(true); } static void doo(object arg) { int id = (int)arg; PrintStatus(id, "等待"); semaphore.WaitOne(); PrintStatus(id, "進入"); PrintCount(1); Thread.Sleep(r.Next(1000)); PrintStatus(id, "退出"); PrintCount(-1); semaphore.Release(); } //輸出線程狀態 static void PrintStatus(int id, string s) { Console.WriteLine("線程{0}:{1}", id, s); } //修改並輸出線程數量 static void PrintCount(int add) { Interlocked.Add(ref count, add); Console.WriteLine("=> 信號量值:{0}", Interlocked.Exchange(ref count, count)); }
輸出
線程1:等待 線程2:等待 線程3:等待 線程1:進入 => 信號量值:1 線程4:等待 線程1:退出 => 信號量值:0 線程5:等待 線程2:進入 => 信號量值:1 線程2:退出 => 信號量值:0 線程5:進入 => 信號量值:1 線程5:退出 => 信號量值:0 線程4:進入 => 信號量值:1 線程4:退出 => 信號量值:0 線程3:進入 => 信號量值:1 線程3:退出 => 信號量值:0