1. 程式人生 > >muduo網路庫架構總結

muduo網路庫架構總結

目錄

muduo網路庫架構總結


本篇檔案會結束muduo網路庫部分學習的筆記,總結一下muduo網路庫的模組組成,同時會提供筆記中個模組的實現程式碼,這些模組程式碼單獨抽出同時去除了muduo中對boost的依賴,改用c++11中的元件或者用單獨的類替換,使得其實現會更為簡潔。

muduo網路庫服務端的類圖

muduo網路庫模組組成

muduo是一個高質量基於事件驅動型的網路庫,其核心程式碼不超過4500行,使用的non-blocking IO(IO multiplexing)+ one loop per
thread模型。此模型每個IO執行緒裡面只有一個事件迴圈(即一個Reactor),處理處理讀寫和定時事件,啟用的事件通過回撥方式提供使用者處理業務邏輯。

Recator反應器

Reactor由三部分組成,EventLoop、Poller、Channel.
EventLoop即IO執行緒中的事件迴圈.它能確保所有註冊的事件都在EventLoop物件所在的執行緒中執行,不用考慮事件的併發。它是執行緒安全的,允許其他執行緒往EventLoop裡面塞東西。

Poller 是IO multiplexing的封裝,它是EventLoop的組成,與EventLoop的生命期相當,為EventLoop提供poll()方法。

Channel 每個Channel物件自始至終只負責一個檔案描述符(fd) 的IO事件分發,但它不擁有這個fd,也不會在析構的時候關閉這個fd。每個Channel物件自始至終只屬於一個EventLoop,因此每個Channel物件都只屬於某一個IO執行緒。 Channel會把不同的IO事件分發為不同的回撥, 例如ReadCallback、 WriteCallback等

Reactor結構實現可參閱我的筆記二 muduo學習筆記(二)Reactor關鍵結構
Reactor部分實現原始碼及簡單測試 : https://github.com/BethlyRoseDaisley/SimpleMuduo/tree/master/Reactor

EventLoop的兩個元件

TimerQueue定時器

TimerQueue 並未在類圖中單獨給出,它是EventLoop的元件,為EventLoop提供了定時任務,和週期任務的介面。通過註冊一個Timerfd到Poller實現.

TimerQueue的實現可參閱我的筆記三 muduo網路庫學習筆記(三)TimerQueue定時器佇列
TimerQueue實現部分原始碼及簡單測試 : https://github.com/BethlyRoseDaisley/SimpleMuduo/tree/master/TimerQueue

Eventfd

Eventfd 這個就是其他執行緒能往EventLoop執行緒裡面塞任務的實現核心,它是 一個事件檔案描述符fd,EventLoop通過將它註冊到Poller,當其他執行緒往EventLoop裡面塞任務的時候,先將任務儲存在EventLoop的容器中,然後啟用Eventfd,處理容器中儲存的任務,當然賽任務需要一把鎖來保護。

Eventfd的實現可參閱我的筆記四 muduo網路庫學習筆記(四) 通過eventfd實現的事件通知機制

Connector和Acceptor聯結器和監聽器

Acceptor

Acceptor它是服務端TcpServer類的主要元件,封裝服務端的連線監聽部分,accept的描述符可讀,表明有新的連線上來,然後通過回撥告知使用者有新的連線上來。

Acceptor的實現可參閱我的筆記五 muduo網路庫學習筆記(五) 連結器Connector與監聽器Acceptor
Acceptor實現部分原始碼及簡單測試 : https://github.com/BethlyRoseDaisley/SimpleMuduo/tree/master/Acceptor

Connector

在非阻塞網路程式設計中,發起連線的基本方式是呼叫connect(2),當socket變得可寫時表明連線建立完畢,但是其中要處理各種型別的錯誤,muduo中把它封裝為Connector class.
Connector 和 Acceptor 設計思路基本一致,只是Acceptor通過判斷套接字是否可讀來執行回撥,而Connector是判斷套接字是否可寫來執行回撥,但是要注意的是socket可寫不一定就是連線建立好了 , 當連線建立出錯時,套介面描述符變成既可讀又可寫,這時我們可以通過呼叫getsockopt來得到套介面上待處理的錯誤(SO_ERROR),如果錯誤是0表示連線成果。

Connector的實現可參閱我的筆記五 muduo網路庫學習筆記(五) 連結器Connector與監聽器Acceptor
Connector實現部分原始碼及簡單測試 : https://github.com/BethlyRoseDaisley/SimpleMuduo/tree/master/Connector

TcpConnection tcp連線

Buffer muduo中的buffer通過vector和一個棧上空間實現,動態可調,其結構很精妙,感興趣的話建議直接閱讀陳碩Buffer部分設計的文章. 這個buffer主要做為TcpConnection的元件。
Socket 封裝一個套接字,管理了這個套接字描述符的生命期,是TcpConnection的元件,TcpConnection 通過這個套接字描述符註冊讀寫事件,SocketHelp一個純介面檔案,封裝了Socket的操作介面。
TcpConnection 封裝一條Tcp連線, 處理這條連線中的讀寫及錯誤,連線關閉等事件,這些事件會在TcpConnection的內部先進行處理,然後通過回撥函式將TcpConnection緩衝中的資料提供給使用者處理。

TcpServer和TcpClient

Tcpserver 主要元件Acceptor,有新的連線到來時會new一個TcpConnection儲存在ConnectionMaps(TcpConnection共享指標的一張對映表)中,通過建立時註冊的名字索引管理所有的連線;有資料可讀時通過MessgeCallBack回撥提供使用者使用。
TcpClient 主要元件Connector, 它的實現幾乎與TcpServer甚似,只不過每個TcpClient只管理一個TcpConnection。

Reactor部分和EventLoop的元件理解後,TcpConnection和TcpServer部分就很好看懂了,所以也沒有單獨寫新的文章。
TcpServer實現部分原始碼及簡單測試 : https://github.com/BethlyRoseDaisley/SimpleMuduo/tree/master/TcpServer
TcpClient實現部分原始碼及簡單測試 : https://github.com/BethlyRoseDaisley/SimpleMuduo/tree/master/TcpClient

muduo中的執行緒安全日誌

AsyncLogging非同步日誌

AsyncLogging一個C++Stream風格的多執行緒安全非阻塞日誌,是muduo庫中的另一個部分組成。
AsyncLogging實現可參閱我的筆記 一個輕巧高效的多執行緒c++stream風格非同步日誌(一)
AsyncLogging實現可參閱我的筆記 一個輕巧高效的多執行緒c++stream風格非同步日誌(二)
AsyncLogging實現部分原始碼 : https://github.com/BethlyRoseDaisley/SimpleMuduo/tree/master/AsyncLogging