情景一中,我主要介紹了用於解決資源爭用時各類方式的區別,本篇文章咱們將進一步介紹線程同步的第二種場景。html
情景二:數量有限,先到先得函數
情景簡介:與情景一相似,可是此次茅坑的數量不僅一個。若是有需求的人數少於茅坑數量,那一切都很和諧。可是人數超過茅坑數量的時候該怎麼辦?多我的佔用一個坑?post
解決辦法:當全部茅坑都客滿的時候,其餘人必須乖乖等在外面,只有當有人從裏面出來的時候,下一我的才能進去。spa
問題抽象:當某一資源同一時刻容許必定數量的線程使用的時候,須要有個機制來阻塞多餘的線程,直到資源再次變得可用。操作系統
線程同步方案:Semaphore、SemaphoreSlim線程
方案特性:限量供應;除全部者外,其餘人無條件等待;先到先得(誰先進茅坑,誰先用,沒有前後順序)code
各方案間的區別htm
Semaphore 的中文名稱叫信號量,在學操做系統的時候確定都會講到。而扯到信號量,最常拿來舉的就是生產者與消費者的例子。與上一篇同樣,我不會在這裏重複介紹一些網上多的是的內容,你們若是有興趣,能夠本身去找度娘、必硬或谷哥。blog
在繼續閱讀前,請確保你已經對用戶模式構造、內核模式構造和混合模式構造有所瞭解,若是還沒有了解,建議您先閱讀情景一中相關章節。進程
Semaphore 經過在構造函數中傳入容器大小來限制一次性容許訪問的線程數量。與情景一介紹中的 Mutex 同樣屬於內核模式,並且都擁有同一個祖宗:WaitHandle。可是與 Mutex 不同的是,經過線程一獲取的全部權,能夠由線程二來釋放。下面的寫法是徹底合法的。
Task.Factory.StartNew(() => { //相似於消費者 semaphore.WaitOne(); Thread.Sleep(5000); }); Thread.Sleep(1000); Task.Factory.StartNew(() => { //相似於生產者 semaphore.Release(); });
優勢:提供數量限制的能力,能夠跨進程使用。
//進程一 Semaphore s = new Semaphore(1, 1, "myname", out creaded); //進程二 Semaphore s = Semaphore.OpenExisting("myname");
缺點:速度慢於用戶模式、混合模式構造,稍快於 mutex。
SemaphoreSlim 是 .Net 4.0 時引進的一個新類型,使用方式上相似 Semaphore,是輕量級的 Semaphore。不容許跨進程使用。
優勢:提供數量限制的能力;速度快,優於 Semaphore。
缺點:不能跨進程使用。
本篇文章介紹的方法主要用於解決資源有限(數量大於一)時線程同步的問題。若是資源惟一,那利用 Semaphore s = new Semaphore(1,1) 的效果與建立一個 Mutex 的效果實際是一致的。而此時的 Semaphore 會有一個新名稱叫 Binary Semaphore (二元信號量)。
那何時該使用 Semaphore, 何時使用 Mutex?
記住本系列強調的情景!若是用於資源爭用,請使用 Mutex;若是用於限量使用請使用 Semaphore。
本文來自《C# 基礎回顧: 線程同步的情景之二》