C++併發程式設計框架Theron(2)——Theron的五要素
1 前言
第一章主要介紹了Theron框架的基礎知識以及其核心Actor模型,其中Actor模型憑藉其與生俱來的高併發模式得到越來越多的關注。例如圍繞其構建的Scala或ErLang語言,還有其它如Java語言中專門的Actor模型框架,本次Theron框架正是基於Actor模型構建的C++多執行緒開發框架。而在這篇博文中,我還是延續上一篇博文擴充介紹Theron框架的五要素,這也是Theron框架最基礎的內容,下面我們直接進入正題。
2 Theron框架五要素
2.1 Actor模型
第一章已經描述過Actor模型的訊息通訊機制以及高併發執行的優勢,成功的避開了互斥體和鎖程式設計方式的困擾,可以說Actor模型就是Theron框架大廈的根基(相關的Actor模型理論我這裡不再重複,請直接閱讀系列博文的第一篇)。而藉助傳統共享記憶體的執行緒併發方式來構建多執行緒應用絕對是一個頭痛的活,對於沒有多執行緒開發經驗的程式設計師而言簡直是噩夢。
2.2 actors
actors是Theron程式的基礎單元,就好比物件導向程式語言中的物件objects,但是所有actors之間是天生並行獨立的,不可以有直接呼叫其他物件的行為,只能通過訊息相互通訊,這與類物件object存在很大的不同,如下圖所示。
圖1 actors之間相互獨立,通過訊息機制相互通訊
每個actor有自己唯一區別的名字和地址,這個地址是唯一標誌每個actor的標籤,它們就是通過這個地址相互交換資訊,就像人與人之間信件通訊的家庭住址。而訊息在傳送的時候是拷貝一份再發出去的,也就是這個訊息只是內容相同但是儲存的地址是各自獨立的,這樣才能保證真正的記憶體獨立。原始碼中有相應的獲取各個actor的地址介面函式GetAddress(),所以每個actor的地址是可以輕鬆查詢到的,這些內容我們後面再詳細的介紹。 而為了確保訊息在傳送的時候可以被拷貝一份,所以Theron框架中可以相互通訊的訊息要求必須是可以被拷貝的物件,例如std::string或其他有拷貝建構函式的類物件等。
2.3 訊息處理器(Message Handlers)
它定義了每個actor響應訊息所要執行的程式,而這些程式是我們預先定義的私有成員函式。程式執行後,只要actors收到訊息,它們的訊息處理器就會對應被自動觸發,並且被一個共享執行緒池併發執行。這裡我們可以認為每個actor的整個生命週期就是由接收訊息和響應訊息組成,這個訊息處理器就相當於每個actor的舉止表現:會檢驗接收到的是什麼訊息,會更新內部狀態,以及可能傳送訊息給其他actors。
actors可以註冊任何數量任何不同型別訊息的處理器。相同,它們也可以註冊任何數量的處理器來處理一種型別的訊息。當一個actor收到一條訊息,對應型別的訊息就會被檢測,並且所有對應訊息型別的處理器被排程執行。訊息處理器的排程確保一次至多有一個該actor的處理器能夠執行。一個actor的所有處理器是假設被該actor包含的“虛擬”執行緒所執行的,而實際當中,這些處理器是被很多actors間共享的執行緒工作池所執行的。
2.4 frameworks
Theron允許被稱為frameworks的子系統來統一組織管理actors。每個framework都擁有自己的一個執行緒池(thread pool),專門用來執行在其下注冊的actors。而跨framework管理其他frameworks的actors是被禁止的。
在每個framework被建立的時候,我們可以詳細說明初始化執行緒數量,處理器關聯性和frameworks的收益策略,並且允許為實時,低延時和時序要求嚴格的應用建立專用的frameworks。
2.4.1 工作執行緒池
此處我想重點介紹一下Theron的執行緒池,也就是解釋一下frameworks在Theron框架中存在的必要性。前面已經介紹過了,每個actor都有一個自己獨一無二的執行緒,這些執行緒是用來當actor無論什麼時候收到一條訊息,各種訊息處理器能被其立即執行。如此一來,我們明顯有一種方法來完成這個基於actor的系統:任何時間一個actor被構建,然後我們開啟一個獨立執行緒取完成這個actor的活。但是這樣設計有個很大的缺點,就是很容易快速建立大量的執行緒,這自然是我們不希望看到的。所以在Theron系統中,actor的訊息處理器是被一個固定的工作執行緒池所執行的。這中方法設計被稱為M:N結構,即我們有M個併發實體,但是實際執行緒數量是N個,兩者不對等。執行緒池中執行緒的數量可以在初始例項化framework物件時候設定,預設情況下是兩個執行緒。
一旦actors接收到訊息,這些訊息就會被按隊排放在一個執行緒安全的工作隊中(work queue),並且工作執行緒就會從執行緒池中被新到達的活喚醒。這個被喚醒的執行緒立即從佇列中檢索一個actor,並且執行這個actor接收到的某個型別的訊息對應註冊繫結的訊息處理器。整個執行緒池檢索過程如下圖2所示。
圖2 執行緒池中執行緒檢索actors的訊息佇列
這裡需要注意下面幾個地方:
Ⅰ 一旦一個工作執行緒開始執行一個actor的訊息處理器,它就會一直執行它們到結束,而不會半途切換到一個新的actor。這就意味著存在糟糕行為的(例如訊息處理器容易卡死)的actors可以餓死整個系統中其他actors。例如預設執行緒池中有兩個執行緒情況下,假設現在我們有三個actor,其中兩個actors的訊息處理函式處於死迴圈狀態,那麼執行緒池的兩條執行緒就被它兩個actors所霸佔,另一個actor就會永遠不會被執行。
Ⅱ 為了確保actors不會被無期限的餓死,使用者需要在程式中合理的考慮啟用執行緒的數量(即執行緒池中執行緒的數量)。當然,此處執行緒數量越多,actors被餓死的概率越小,CPU利用率也會更高。但是受硬體物理核的限制,我們自然不可以無節制的增加執行緒的數量,過量執行緒只會增加執行緒過度切換的開銷,這是程式設計得不償失的。所以合理分配執行緒的數量才是最完美的,這個需要我們自己權衡是想更多執行緒併發執行還是想提高程式的效率。
Ⅲ 假如我們為每個actor某個型別的訊息註冊繫結了多個訊息處理器(處理函式),那麼從執行緒池中被喚醒的一個執行緒會序列按註冊順序將這些訊息函式依次都執行完成。
2.5 距離無限制特性
因為Actor模型不會有別區分相鄰和遠距離的actors,所以各個遠距離伺服器上子應用間聯絡和同步是無縫對接的。在相同的程式中,訊息傳送可以很自然的在遠端主機間運作,這個沒有距離限制的特性使得Theron框架非常適合分散式應用開發,就像多執行緒程式開發一樣簡單。
4 小結
這篇博文主要介紹了Theron框架的五要素,包括Actor模型,actors物件,frameworks,工作執行緒池以及距離無限制特性。這些事Theron框架的基礎,可以大致瞭解一番,後面再根據例項慢慢體會每個要素的特性以及功能。在後面文章中,我也會慢慢轉為實戰和介紹程式,到此我相信你對Theron框架已經有了一個大致的瞭解了。
以上是個人學習記錄,由於能力和時間有限,如果有錯誤望讀者糾正,謝謝!
轉載請註明出處:http://blog.csdn.net/FX677588/article/details/74936625
參考文獻:
Theron框架官網http://www.theron-library.com/
詳解Theron通過Actor模型解決C++併發程式設計的一種思維http://www.mahaixiang.cn/bcyy/954.html
相關文章
- Java 併發程式設計 Executor 框架Java程式設計框架
- 《java併發程式設計的藝術》併發容器和框架Java程式設計框架
- 《java併發程式設計的藝術》Executor框架Java程式設計框架
- Java併發程式設計的藝術(五)——中斷Java程式設計
- [仁潤雲技術團隊]併發程式設計-(2)併發程式設計的目標程式設計
- 深入淺出 Java 併發程式設計 (2)Java程式設計
- java面試-Java併發程式設計(五)——中斷Java面試程式設計
- 併發程式設計程式設計
- 併發程式設計:DEMO:比較Stream和forkjoin框架的效率程式設計框架
- 2. Go併發程式設計--GMP排程Go程式設計
- java併發程式設計系列:java併發程式設計背景知識Java程式設計
- Java併發程式設計的藝術,解讀併發程式設計的優缺點Java程式設計
- Java併發程式設計---java規範與模式下的併發程式設計1.1Java程式設計模式
- Python併發程式設計Python程式設計
- 併發程式設計 synchronized程式設計synchronized
- Go 併發程式設計Go程式設計
- 併發程式設計(ReentrantLock)程式設計ReentrantLock
- Java併發程式設計Java程式設計
- 併發程式設計(四)程式設計
- 併發程式設計(二)程式設計
- golang併發程式設計Golang程式設計
- Golang 併發程式設計Golang程式設計
- 併發程式設計13程式設計
- java 併發程式設計Java程式設計
- 併發程式設計—— LinkedTransferQueue程式設計
- .NET 中的併發程式設計程式設計
- Go 併發程式設計 - 併發安全(二)Go程式設計
- JUC併發程式設計學習(五)集合類不安全程式設計
- 《java併發程式設計的藝術》併發工具類Java程式設計
- c++11併發程式設計歷程(15):併發設計以及併發設計資料結構的思考C++程式設計資料結構
- .NET的併發程式設計(TPL程式設計)是什麼?程式設計
- Java併發程式設計(07):Fork/Join框架機制詳解Java程式設計框架
- Java併發程式設計 - 第十一章 Java併發程式設計實踐Java程式設計
- 【Java併發程式設計】一、為什麼需要學習併發程式設計?Java程式設計
- Python併發程式設計之從效能角度來初探併發程式設計(一)Python程式設計
- 併發程式設計之:JUC併發控制工具程式設計
- Java併發程式設計-鎖及併發容器Java程式設計
- 併發程式設計(二)——併發類容器ConcurrentMap程式設計
- Java併發程式設計ForkJoin的DemoJava程式設計