若是须要查看更多文章,请微信搜索公众号 csharp编程大全,须要进C#交流群群请加微信z438679770,备注进群, 我邀请你进群! ! !html
emaphore:可理解为容许线程执行信号的池子,池子中放入多少个信号就容许多少线程同时执行。编程
本文连接:微信
https://www.cnblogs.com/yifengjianbai/p/5468449.html并发
百度百科:Semaphore,是负责协调各个线程, 以保证它们可以正确、合理的使用公共资源。也是操做系统中用于控制进程同步互斥的量。操作系统
Semaphore经常使用的方法有两个WaitOne()和Release(),Release()的做用是退出信号量并返回前一个计数,而WaitOne()则是阻止当前线程,直到当前线程的WaitHandle 收到信号。这里我举一个例子让你们更容易理解:当咱们这样实例化Semaphore时候线程
Semaphore sema = new Semaphore(x,y)有一队人排队上洗手间,人就至关于线程,x为还剩余的位置数量,y为总的位置数量。3d
WaitOne()方法就至关于人在等待洗手间位置的行为,而Release()方法就至关于一我的从洗手间出来的行为,这里再假设x和y都为5,说明开始的时候洗手间有5个空位置,且总共只有5个位置,当一队超过5我的的队伍要上洗手间的就排队,首先WaitOne()方法等待,发现有空位就依次进去,每进去一个空位减一,直到进去5以后个没有空位,这时候后面的人就一直等待,直到进去的人从洗手间出来Release()方法,空位加一,在等待WaitOne()方法的人发现有空位又进去一个空位减一……如此循环往复。orm
请看下面例子:htm
public class Program { static Semaphore sema = new Semaphore(5, 5); const int cycleNum = 9; static void Main(string[] args) { for(int i = 0; i < cycleNum; i++) { Thread td = new Thread(new ParameterizedThreadStart(testFun)); td.Name = string.Format("编号{0}",i.ToString()); td.Start(td.Name); } Console.ReadKey(); } public static void testFun(object obj) { sema.WaitOne(); Console.WriteLine(obj.ToString() + "进洗手间:" + DateTime.Now.ToString()); Thread.Sleep(2000); Console.WriteLine(obj.ToString() + "出洗手间:" + DateTime.Now.ToString()); sema.Release(); } } 复制代码
这里我要说明一点,信号量控制的只是线程同步的量,而无论顺序,这个例子来讲线程控制的就是线程同步量为5,也就是同时并发的线程数量为5个,至因而哪一个先哪一个后不是由这里的信号量决定的。blog
固然这个例子中因没有作什么复杂的操做,通常状况进入线程的时间和每一个线程要的时间不会有太大差异,因此执行的顺序仍是很规律的(为了说明这个问题我也是运行了屡次才让结果稍有不一样,这里编号2抢在了编号1前面就是这个道理),若是线程中有很复杂的操做每一个线程在运行中所用的时间有比较大的差异,或者循环开始有复杂操做那么极可能就不是编号0先进入洗手间了,且不必定是先进入的就会先出来。
接下来再简单介绍一下Semaphore的WaitOne()和Release()的重载方法
public int Release(int releaseCount);releaseCount指的是释放的信号量数量,若是没有参数默认为1,Release()就至关于Release(1)
这里要说明一点,当Release()或者Release(int releaseCount)执行时致使信号量计数大于最大数量时会抛出SemaphoreFullException异常。下面这种状况就会异常:
Semaphore sem = new Semaphore(4,5);
sem.Release(2);//这里是释放2个信号量加上以前的4个,超出5个了
public virtual bool WaitOne(TimeSpan timeout);
public virtual bool WaitOne(int millisecondsTimeout);第一个重载参数timeout:指定时间间隔,若在这段时间内没有接收到信号则跳过等待继续执行
第二个重载参数millisecondsTimeout:指定时间间隔整数毫秒,若在这段时间内没有接收到信号则跳过等待继续执行
WaitOne()还有两个重载方法不是很经常使用这里就不介绍了。上面的重载方法这里也再也不进了案例说明了,有兴趣的朋友能够本身尝试一下。
说明:
一、若是semaphore.Release(n),n>semaphore最大容纳信号量,将出异常。二、当semaphore拥有的信号量为1时,Semaphore至关于Mutex三、当semaphore拥有的信号量>1时,信号量的数量便可供多个线程同时获取的个数,此时可认为获取到信号量的线程将同时执行(实际状况可能与CPU核心数、CPU同时支出线程数有关)