分享
 
 
 

【.NET深呼吸】线程信号量(Semaphore)

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: |||超大  

Semaphore类可以控制某个资源允许访问的线程数,Semaphore有命名式的,也有不命名的;如果不考虑跨进程工作,一般在代码中使用不命名方式即可。

信号量有点类似于等待句柄,某个线程如果调用了WaitOne方法,这个线程就会暂停,并且等待有可用的信号量时才会继续执行;某个线程调用Release方法,就会释放一个信号计数值,每调用一次就释放一个,如果想一次性释放N个信号,可以调用Release(int)重载,把要释放的数量传递给方法参数,但这个数值不能超过Semaphore实例化时所指定的最大值,否则会引发异常。

Semaphore构造函数可以指定允许的最大信号量,以及默认的信号量。声明如下:

Semaphore(intinitialCount,intmaximumCount);

maximumCount参数指定该对象允许的最大信号量;initialCount参数指定默认值,这个默认值不能超过maximumCount指定的最大值。即该Semaphore实例默认允许多少个线程收到信号(访问资源)。

当某个占用资源的线程调用Release方法后,它会释放出一个或多个信号,这时候,其他等待的线程就可以继续执行。

只要是涉及到线程问题都特别难说清楚,相当抽象,相当考验人的理解能力。

比如,图书馆里面有五本《X瓶梅》,但想借这本书的有20人。前面五个人自然很轻松就借到(进入访问圈,这五个线程以外的线程等待),其他人只好等了。

过了几天后,有个家伙通宵看书,终于看完了,因此他还了书,这时候,剩下的15个人看谁的动作快,可以借到刚还回去的这本书。

再过了几天,又有两个人看完了,还书。此时,剩下的14个人中,有两个人可以借得此书。

大概的原理就是这样,下面看看例子。

classPRogram

{//生成随机数,以延迟每个任务的执行时间staticRandom rand =newRandom();//声明Semaphore变量,以控制线程信号量staticSemaphore sm =null;staticvoidMain(string[] args)

{

sm=newSemaphore(1,4);//实例化//启动10个任务for(inti =0; i <10; i++)

{

Task t=newTask(DoWork,"任务"+ (i +1));

t.Start();

}//防止DOS窗口立即退出Console.Read();

}privatestaticasyncvoidDoWork(objectp)

{

sm.WaitOne();//等待花开stringtn = p?.ToString();

Console.WriteLine($"{tn} 已获得访问。");awaitTask.Delay(rand.Next(1,10) *1000);//释放sm.Release();//花谢了Console.WriteLine($"{tn}已释放。");

}

}

多线程开发我最喜欢用Task类,方便简单强大好用高大上,而且它还能自行处理CPU多个核的问题。在上面例子中,有10个任务要执行,但我所实例化的Semaphore对象给的最大访问线程数为4,而默认状态下只允许1个线程同时访问。

所以,10个任务启动后,其中一个会抢到访问权,其他任务就等吧。这时候Semaphore对象可访问数为0。因为默认只允许1,现在有一个线程抢了,所以剩下就是0个访问权了。

当这个抢到访问权的任务调用Release方法后,访问权被释放,这时候剩下的9个任务就开始抢,谁抢到谁就执行……依此类推。

看看运行结果。

任务1手快,它先抢到了访问权,于是它dododo,do完后,调用Release方法释放,然后任务3人品好,就抢到了访问权,然后XXXXX,X完后调用Release释放。其他线程继续抢……

估计看完以上例子后,大家应该有点头绪了。

现在,我们把上面的代码改一下,在初始化Semaphore对象时的默认值从1改为3。

sm =newSemaphore(3,4);

默认允许3个线程同时访问资源,最大数量为4。

然后再次运行,结果如下:

因为默认允许3个线程同时进入,所以在输出结果中,前面三个任务都能获取访问权,而其他的任务只能等待机会。当前面已获得资源的三个任务中有一个或者N个进行释放后,剩下的任务又开始抢机会。

本文示例下载地址:http://files.cnblogs.com/files/tcjiaan/DemoApp.zip

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有