《面向模式的软件体系结构2-用于并发和网络化对象模式》读书笔记(17)--- 领导者/追随者...
5.4領導者/追隨者(Leader/Follower)
1.問題
? ? ? 多線程是實現并發處理多事件的應用程序的一種常用技術。然而,很難實現高性能的多線程服務器應用程序。這些應用程序通常處理大量同時到達的多類型事件。為了有效地處理這種問題,有三個強制條件必須解決:
? ? ? 1)服務請求可以來自為每個已連接的客戶機分配的多事件源(如多TCP/IP套接字句柄)。因此,一個關鍵設計強制條件是在線程和事件源間確定有效的多路分解關聯。
? ? ? 2)為了將性能最大化,必須盡量減少引起與并發有關的開銷。(如語境切換,同步化和緩存一致性管理)。特別地,為在多個線程間傳遞的請求動態分配內存的同步模型會在傳統的多處理器操作系統中產生巨大的開銷。
? ? ? 3)多路分解共享的事件源集合上事件的多個線程必須相互協作,以防止競爭條件。競爭條件可能出現在多個線程試圖同時訪問或修改某些類型的事件源的時刻。
?
2.解決方案
? ? ? 構造一個線程池,通過對到達事件源的事件多路分解,并向處理事件的應用服務同步地分配事件,依此輪流進行來共享事件源集合。
? ? ? 詳細細節:設計一個線程池機制,允許其中的多個線程相互協作并在檢測、多路分解、分配和處理事件時保護臨界區。在這種機制中,每次允許一個線程(領導者)等待在事件源集合上出現一個事件。同時,其他線程(追隨者)排隊等待它們成為領導者的機會。當前的領導者線程從事件源集合檢測到一個事件后,它首先將一個追隨者線程提升為新的領導者,然后扮演處理線程的角色,對事件多路分解并分配給指定的事件處理程序,在處理線程中實現與應用有關的事件處理。在當前領導者線程在由所有線程共享的事件源集合上等待新的事件時,多個處理線程可以并發地處理事件。在處理完事件后,處理線程恢復到追隨者角色,并等待再次成為領導者線程。
?
3.結構
? ? ? 由操作系統提供句柄,用來區分可以生成事件并將之排隊的事件源(如網絡連接或打開文件)。事件可以由外部事件源(如從客戶機發送一個服務的CONNECT事件或READ事件),或者內部事件源(如超時)引發。句柄集是句柄的集合,可以用來等待一個或多個事件在該句柄集中的句柄上發表。當可以激活句柄集中句柄上的一個操作而不發生操作阻塞時,句柄集返回到它的調用者。
? ? ??
?
? ? ? 事件處理程序明確了由一個或多個鉤子方法組成的接口。這些方法表示可以對發生在句柄上的與應用有關的事件進行處理的操作集。
? ? ? 具體事件處理程序是事件處理程序的特化,并實現應用程序提供的特定服務。特別地,具體事件處理程序實現負責處理從句柄接收的事件的鉤子方法。
? ? ??
?
? ? ? 領導者/追隨者模式的核心是線程池。一個或多個線程扮演追隨者角色并在線程池同步器上排隊等待扮演領導者角色。其中一個線程被選擇成為領導者,等待事件在句柄集中的句柄上發生。當有一個事件發生時,當前領導者線程將一個追隨者線程提升為新的領導者。原來的領導者接著扮演處理線程的角色,對從句柄集到相應事件處理程序的事件進行多路分解,并分配處理程序的鉤子方法進行事件處理。在處理線程完成了事件的處理后,它再次返回扮演追隨者線程的角色,在線程池同步器上等待再次成為領導者線程。
? ? ? ?
?
4.實現
1)選擇句柄和句柄集機制。句柄集是句柄的集合,領導者線程可以用它來等待在事件源集上發生事件。開發者通常選擇底層操作系統提供的句柄和句柄集機制,而不是隨便地實現它們。
? 1.1)確定句柄類型。
? ? ·并發句柄。這種類型的句柄允許多個線程并發訪問事件源的句柄而不會引發可能破壞,丟失或擾亂數據的競爭條件。
? ? ·迭代句柄。這種類型的句柄需要多線程迭代訪問事件源上的句柄,因為并發訪問將導致競爭條件。?
? 1.2)確定句柄集的類型。
? ? ·并發句柄集。這種類型的句柄集上可以有并發的動作,例如,線程池對它的并發訪問。
? ? ·迭代句柄集。這種類型的句柄集在它可以啟動句柄集中一個或多個句柄上的一個操作而不阻塞操作時返回到它的調用者。雖然迭代句柄集可以在單個調用中返回多個句柄,但是它一次只能由一個線程調用。
? 1.3)確定選擇某個句柄和句柄集機制的效果。
? 1.4)實現事件處理程序的多路分解機制。
? ? ·對低層操作系統事件多路分解機制編程。在這種策略中,直接使用操作系統提供的句柄集多路分解機制。
? ? ·對高層事件多路分解模式編程。在這種策略中,開發者使用諸如反應器、主動器和包裝器材外觀等高層模式。
2)在句柄集中實現臨時激活(停用)句柄的協議。當事件到達時,領導者線程執行以下三步:
? ? ·在句柄集中暫時停用該句柄。
? ? ·將一個追隨者線程提升為新的領導者。
? ? ·繼續處理事件。
? ? 在句柄集中將該句柄停用避免了從選擇新領導者到處理事件的時間內出現競爭條件。如果新的領導者在這一段時間內等待句柄集中的同一句柄,那么它可能再次將該事件多路分解,這樣做是錯誤的,因為這時已經在進行分配了。在事件被處理后,句柄在句柄集中被再次激活,這樣領導者線程等待事件在該句柄或句柄集中其他激活的句柄上出現。
3)實現線程池。為了將一個追隨者線程提升為領導者角色,以及確定哪個線程是當前的領導者,領導者/追隨者模式的工具必須管理一個線程池。一種直接的實現方法是簡單地將所有追隨者線程放入集合,等待單獨的同步器,如信號燈和條件變量。在這種設計中,不管是哪個線程來處理事件,只要共享句柄集的池中的所有線程都是串行化的。
4)實現允許線程初次加入(以及以后再次加入)線程池的協議。該協議用于以下兩種情況:
? ? ·在首創了能獲得和處理事件的線程池后。
? ? ·以及在處理線程已完成并且可以處理另一個事件時。
? ? 如果沒有領導者線程可用,則處理線程可以立即變為領導者。如果領導者線程已經獲得,一個處理線程可以在線程池同步器上等待變成追隨者。
5)實現追隨者提升協議。
? 5.1)實現句柄集同步協議。如果句柄集是迭代的,并且我們盲目地提升了一個新的領導者線程,那么可能新的領導者線程會試圖處理與前一個領導者線程檢測到的并正在進行處理的同一事件。為了避免這種競爭條件,必須在將一個追隨者句柄提升為領導者句柄并將事件分配給具體事件處理程序之前,將該句柄從句柄集的候選句柄中刪除。分配并處理事件后,必須從句柄集中再次激活該句柄。
? 5.2)確定提升協議排序。
? ? ·LIFO順序。在許多應用程序中,下一次提升哪個追隨者線程不重要,因為所有線程都是對等的。在這種情況下,領導者線程可以按照后進先出(LIFO)的順序提升追隨者線程。LIFO協議通過確保等待時間最短的線程首先被提升將CPU高速緩存的相似性最大化。
? ? ·優先級順序。在某些應用程序中,特別是實時應用程序中,線程可能運行在不同的優先級上。在這種情況下,需要根據追隨者線程的優先級對它們進行提升。這種協議可以使用某些類型的優先級隊列實現,如堆。雖然該協議比LIFO協議更復雜,但是為了使優先級反序的情況最少,就需要按照追隨者線程的優先級對它們進行提升。
? ? ·由實現定義的順序。在使用操作系統同步器(如信號燈或條件變量)來實現句柄集時常用這種順序,通常按照由實現定義的順序分配等待線程。這種協議的優點是它能高效地映射到本地操作系統同步器上。
6)實現事件處理程序。?
?
5.結論
優點:
1)性能增加。
? ·增強了CPU高速緩存相似性并消除了動態內存分配和線程間共享的數據緩沖區要求。
? ·通過在線程間不交換數據的方法來使加鎖開銷達到最小,因此降低了線程同步化。
? ·可能將優先級逆序的數量減少到最小,因為服務器中沒有進行其他排隊。
? ·不需要語境切換以處理每個事件,減少了事件分配延時。
2)編程簡單性。領導者/追隨者模式簡化了并發模型的編程,其中多線程可以使用共享句柄集接收請求,處理響應并多路分解連接。
?
不足:
1)實現復雜性。
2)缺乏靈活性。
3)網絡I/O瓶頸。?
轉載于:https://www.cnblogs.com/pennant/archive/2012/10/02/2709964.html
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的《面向模式的软件体系结构2-用于并发和网络化对象模式》读书笔记(17)--- 领导者/追随者...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DIV+CSS布局图片加阴影效果方法
- 下一篇: eclipse中的感叹号和x号解决方法