C#线程同步(5)- 信号量 Semaphore

文章原始出处 http://xxinside.blogbus.com/logs/47617134.htmlhtml

预备知识:C#线程同步(1)- 临界区&LockC#线程同步(2)- 临界区&MonitorC#线程同步(3)- 互斥量 MutexC#线程同步(4)- 通知&EventWaitHandle一家web

  此次终于不用说太多话了,某人看这一系列博客的反应老是“好长……”,以致于都不肯意看下去。在这一系列开篇以前,本想应该1、两个星期就能解决,结果每篇总要花上一星期左右。总想把涉及的全部方面都讲得尽可能清楚明白,但愿容易被看懂。因而老是不断陷于考虑如何串联各处的关系、要写个怎样的例子、细细考量MSDN的每一句话是否稳当……能作的无用的事情也就这点儿,因此仍是努力地督促着本身要尽快完成。编程

  呵呵,仍是回到正题。信号量也算是个鼎鼎大名的东西吧,提到互斥量总会提及信号量。两者的差异很简单,互斥量、临界区是用于保护“一个”须要被互斥访问的资源,这个资源同时只有一个线程能被访问;而信号量能够被用于管理“资源池”。在.Net中Semaphore类就是对Windows信号量的封装。安全

跟谁更亲,Mutex仍是EventWaitHandle?并发

  本系列的第3篇Mutex、第4篇EventWaitHandle都提到过Semaphore,由于它们同继承于WaitHandle。因此Semaphore必然有着一些咱们已经知道的特性:ide

  • 你能够建立没有名称的“局部”信号量,也能够建立命名的“全局”信号量用于跨应用程序域的同步。
  • 你能够用WaitOne()请求一个资源。
  • 你须要使用try/finally结构调用“Close()”,确保信号量资源在使用后被正确释放。
  • 你仍然须要注意在全局状况下Semaphore的访问安全问题。

  总的来讲,Semaphore与Mutex更像是兄弟,仍然与EventWaitHandle一脉不太亲近:函数

  • Semaphore从机制上来讲跟Mutex同样属于“锁”而不是“通知”,所以跟Mutex同样几乎没有“通知”的能力。
  • 举个不恰当可是很形象的例子,Semaphore就是一个能够屡次进入的“Mutex”。Mutex永远只容许一个线程拥有它,而Semaphore能够容许多个线程请求,所以Semaphore被用于管理一次能够容许多个线程进入并发访问资源的状况。之因此说“不恰当”,是由于一旦容许多个线程访问资源,那么这时候的资源必定不是互斥资源,相应的代码段也再也不是“临界区”。你千万不要觉得咱们在上一篇中提到的“糖罐”里有多颗糖就叫作“资源池”(都说过了嘛一个糖罐必定是须要互斥访问的),除非你有多个糖罐而不是多颗糖。
  • 由于Semaphore与Mutex在请求数量上的不一样,所以他们的线程相关性是不一样的。这一点,Semaphore到跟EventWaitHandle同样,它是线程无关的。也就是说对Semaphore地释放者能够不定是Semaphore的拥有者。好比说我能够是消费者线程总使用WaitOne()请求线程池中的资源历来不须要释放,而生产者老是Release线程池中的资源而历来不请求。

Semaphore的使用方法spa

  若是你已经读过这个系列前面4篇的博文,我想到此为止你已经对Semapore的前因后果、性格特色掌握得八九不离十了。就像开篇所说,此次咱们咱们不要再废不少话来讨论它,大体应该知道的细节,除了上面咱们说的差别,都已经在以前各篇讲过了。线程

  因此我决定要偷懒了:orm

  • Semaphore的构造函数在 这里,是的你会以为已经很熟悉了,一望而知其意。其它的,请仍然记得命名前缀的问题;记得名称仍然是大小写敏感的;最后别忘记使用SemaphoreSecurity类来管理命名信号量的安全。
  • Semaphore仍然使用WaitOne()请求资源,接口都来自WaitHandle,你已经看过不少遍了。
  • Semaphore使用Release()来表示对资源的释放,不过与ReleaseMutex()不一样,这个函数有重载方法容许你指定释放几个资源。这引起了一个问题,若是Release的次数超过资源总量,那么会引起SemaphoreFullException异常。好比线程A和线程B都进入信号量。若是线程B中发生了一个编程错误,致使它调用Release()两次(或者Release(2)),则两次调用都会成功。这样,信号量的计数就已经达到了最大值,因此,当线程A最终调用Release时将引起异常。这至关于原本资源中只有N个资源,最后却有超过N个资源被还回来。
  • 记得使用完之后调用Close()释放信号量资源。

Sample Code

  嘿嘿,没有。由于我实在想不出有什么特别适合Sempore的简单例子,总不能把Mutex那个应用程序单例的例子改为容许启动指定个数吧。等想到了,再来补上吧。就请先参见MSDN上的相关示例代码吧。

相关文章
相关标签/搜索