Semaphore
表示一个命名(系统范围内)或本地信号量。它是对 Win32
信号量对象的封装,Win32
信号量是计数信号量,其可用于控制对资源池的访问。而 SemaphoreSlim
类为一个轻量、快速的信号量,可在等待时间预计很短的情况下,用于在单个进程内的等待
信号量可用于生产者、消费者线程,其中一个线程始终增加信号量计数,另一个始终减少信号量计数
示例代码如下,举一个食堂吃饭的例子
1 using System; 2 using System.Collections.Generic; 3 using System.Threading; 4 using System.Threading.Tasks; 5 6 public class App { 7 static void Main(string[] args) { 8 // 假设共有 10 个学生 9 int studentCount = 10; 10 // 食堂里面共有 4 个位置 11 int seatCount = 4; 12 var semaphore = new SemaphoreSlim(seatCount, seatCount); 13 var eatings = new List<Task>(); 14 for (int i = 0; i < studentCount; i++) { 15 eatings.Add(Task.Run(() => Eat(semaphore))); 16 } 17 Task.WaitAll(eatings.ToArray()); 18 } 19 static void Eat(SemaphoreSlim semaphore) { 20 // 排队中,即等待有空位置出来 21 semaphore.Wait(); 22 try { 23 // 有一个空位,因此可以坐下吃饭了 24 Console.WriteLine("{0}占了一个位置,准备坐下吃饭了", Task.CurrentId); 25 Thread.Sleep(1000); 26 } finally { 27 Console.WriteLine("{0} 已经吃完了,准备让出位置", Task.CurrentId); 28 // 将位置让出来 29 semaphore.Release(); 30 } 31 } 32 }
运行结果如下
1 1占了一个位置,准备坐下吃饭了 2 3占了一个位置,准备坐下吃饭了 3 2占了一个位置,准备坐下吃饭了 4 4占了一个位置,准备坐下吃饭了 5 4 已经吃完了,准备让出位置 6 5占了一个位置,准备坐下吃饭了 7 3 已经吃完了,准备让出位置 8 6占了一个位置,准备坐下吃饭了 9 2 已经吃完了,准备让出位置 10 1 已经吃完了,准备让出位置 11 8占了一个位置,准备坐下吃饭了 12 7占了一个位置,准备坐下吃饭了 13 5 已经吃完了,准备让出位置 14 9占了一个位置,准备坐下吃饭了 15 8 已经吃完了,准备让出位置 16 10占了一个位置,准备坐下吃饭了 17 6 已经吃完了,准备让出位置 18 7 已经吃完了,准备让出位置 19 9 已经吃完了,准备让出位置 20 10 已经吃完了,准备让出位置
相信这个例子可以使我们理解得更加深刻
而对于命名信号量,我们只需要在使用时,按以下方式即可
需要注意的是,SemaphoreSlim
不支持命名信号量
1 Semaphore semaphore = new Semaphore(4, 4, "Named_Semaphore");
转自链接:https://www.jianshu.com/p/a9d16eecee98