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上的相關示例代碼吧。

相關文章
相關標籤/搜索