c#多线程同步之Semaphore

    一提到Semaphore(信号量)的使用,还挺有意思的,它允许多个线程同时访问多个稀有资源,我立马想到银行的ATM机取钱的场景。看下面的代码:

 1        static Semaphore sem = new Semaphore(2, 4);
 2 
 3         public static void StartThread(string name)
 4         {
 5             var t = new Thread(run);
 6             t.Name = name;
 7             t.Start();
 8         }
 9         static void run()
10         {
11             string name = Thread.CurrentThread.Name;
12             Console.WriteLine(name + "正在等待ATM小房子……");
13             //申请一个许可证
14             sem.WaitOne();
15             Console.WriteLine(name + "进入ATM小房子……");
16             Console.WriteLine(name + "开始操作ATM");
17             Thread.Sleep(1000);
18             Console.WriteLine(name + "操作ATM结束");
19             Console.WriteLine(name + " 从ATM小房子出来了……");
20             //释放
21             sem.Release();
22         }
23         static void Main(string[] args)
24         {
25             for (int i = 0; i < 4; i++)
26             {
27                 StartThread("#" + (i + 1));
28             }
29             Console.Read();
30         }
Semaphore构造函数,第一个参数表示当前可用资源数,第二个参数表示最大资源数。可用资源数不能超过最大资源数,否则c#运行时会抛出异常。当初始资源为0时,看看结果:

这个结果说明,4个ATM,当前都有人占用着,所以四个人处于等待状态。

当我们把初始资源数设为4,结果:

上图说明,四个人都没有等待,而是直接进入了ATM机的小房子。当资源足够用的时候,就不存在稀缺资源这么一说了。

当我们把初始资源数设为1时,再次看看结果:

当我们把资源数设置为1时,这时候不就和互斥体产生的效果一样了吗?这就好比众多的病人在一个诊室等着看病一样,医生只能一个一个地来。

      总之,信号量内部维护了一个对稀有资源的计数器,当一个资源被用时(调用WaitOne方法,一直阻塞线程,直到有可用资源),这个计数器-1,当一个资源被释放(调用Release方法)时,这个计数器+1,如果计数器为0时,表示资源耗尽了,那么所有线程都处于等待状态。

 

 

 


posted @ 2017-05-19 15:28  micDavid  阅读(536)  评论(0编辑  收藏  举报