转自:http://www.csharpwin.com/csharpspace/12233r8865.shtml
Semaphore的理解
通过使用一个计数器对共享资源进行访问控制,Semaphore构造器需要提供初始化的计数器(信号量)大小以及最大的计数器大小
访问共享资源时,程序首先申请一个向Semaphore申请一个许可证,Semaphore的许可证计数器相应的减一,当计数器为0时,其他申请该信号量许可证的线程将被堵赛,直到先前已经申请到许可证的线程释放他占用的许可证让计数器加一,这样最近去申请许可证的线程将会得到竞争得到被释放的许可证。
常见的操作方法 WaitOne():申请一个许可证 Release():释放占用的许可证
具体使用看下面的示例代码:
01 | using System; |
02 | using System.Collections.Generic; |
03 | using System.Linq; |
04 | using System.Text; |
05 | using System.Threading; |
06 | |
07 | namespace MutiThread |
08 | { |
09 | /// <summary> |
10 | /// .net 信号量Semaphore的使用 |
11 | /// </summary> |
12 | class Program |
13 | { |
14 | static void Main( string [] args) |
15 | { |
16 | //初始化4个线程 |
17 | Mythread mythrd1 = new Mythread( "Thrd #1" ); |
18 | Mythread mythrd2 = new Mythread( "Thrd #2" ); |
19 | Mythread mythrd3 = new Mythread( "Thrd #3" ); |
20 | Mythread mythrd4 = new Mythread( "Thrd #4" ); |
21 | |
22 | //Join()方法阻塞调用线程 |
23 | //达到主线程在4个子线程执行完毕才退出的目的 |
24 | mythrd1.thrd.Join(); |
25 | mythrd2.thrd.Join(); |
26 | mythrd3.thrd.Join(); |
27 | mythrd4.thrd.Join(); |
28 | |
29 | } |
30 | } |
31 | |
32 | /// <summary> |
33 | /// 封装线程类 |
34 | /// </summary> |
35 | class Mythread |
36 | { |
37 | public Thread thrd; |
38 | //创建一个可授权2个许可证的信号量,且初始值为2 |
39 | static Semaphore sem = new Semaphore(2, 2); |
40 | |
41 | public Mythread( string name) |
42 | { |
43 | thrd = new Thread( this .run); |
44 | thrd.Name = name; |
45 | thrd.Start(); |
46 | } |
47 | |
48 | void run() |
49 | { |
50 | Console.WriteLine(thrd.Name + "正在等待一个许可证……" ); |
51 | //申请一个许可证 |
52 | sem.WaitOne(); |
53 | Console.WriteLine(thrd.Name + "申请到许可证……" ); |
54 | for ( int i = 0; i < 4; i++) |
55 | { |
56 | Console.WriteLine(thrd.Name + ": " + i); |
57 | Thread.Sleep(1000); |
58 | } |
59 | Console.WriteLine(thrd.Name + " 释放许可证……" ); |
60 | //释放许可证 |
61 | sem.Release(); |
62 | } |
63 | } |
64 | |
65 | } |
程序执行结果为: