1. 程式人生 > >C#多執行緒開發10:執行緒同步之Semaphore類

C#多執行緒開發10:執行緒同步之Semaphore類

Semaphore類表示訊號量

訊號量和互斥類似,只是訊號量可以同時由多個執行緒使用,而互斥只能由一個執行緒使用。也就是說,使用訊號量時,可以多個執行緒同時訪問受保護的資源。下面例項演示了“學生到食堂就餐”的場景,一共有10個學生需要就餐,但是食堂每次只能接納4名學生就餐,所以將訊號量的計數設定為4,每次有4個任務(就餐任務)可以獲得鎖定。剩下的學生就必須等待,等到鎖定被解除時,學生才可以繼續獲得鎖定,進入食堂就餐。

using System;
using System.Threading;
using System.Threading.Tasks;
namespace SemaphoreExample
{
    class Program
    {
        static void Main(string[] args)
        {
            int studentCount = 10;
            int seatCount = 4;//小小食堂只有4個位子
            var semaphore = new SemaphoreSlim(seatCount, seatCount);
            var eatings = new Task[studentCount];
            for (int i = 0; i < studentCount; i++)
            {
                eatings[i] = Task.Run(() => Eat(semaphore)); 
            }
            Task.WaitAll(eatings);
            Console.WriteLine("All students have finished eating!");
        }
        static void Eat(SemaphoreSlim semaphore)
        {
            semaphore.Wait();
            try
            {
                Console.WriteLine("Student {0} is eating now!", Task.CurrentId);
                Thread.Sleep(1000);
            }
            finally
            {
                Console.WriteLine("Student {0} have finished eating!", Task.CurrentId);
                semaphore.Release();
            }
        }
    }
}

程式碼的執行結果如下圖所示。

 

使用Semaphore類的例項方法Wait()鎖定訊號量,使用Release()方法可以解除鎖定。

.Net中訊號量有兩個類:Semaphore和SemaphoreSlim。Semaphore類可以命名,允許在不同程序之間同步。SemaphoreSlim類是對於較短等待時間進行了優化的輕型版本。本文中使用的是SemaphoreSlim類。