天天看點

《Muduo 多線程網絡庫解析》

Muduo是C++語言實作的網絡庫,和Anet的設計目标基本一緻,各有千秋。希望通過閱讀Muduo能找到一些不一樣的靈感。

下面是本人最近分享muduo的ppt。性能對比圖和類圖是直接從muduo庫的manual手冊截過來的,其餘的是用libreoffice上畫出來。

概述:

1) muduo的抽象不錯的:概括上來說EventLoop 封裝了對事件的處理,這是client和server共有的邏輯,而且EventLoop和ThreadPool是解耦合的,為多線程IO模型奠定了基礎;TcpServer 封裝了Server端的邏輯和回調,比如acceptor。TcpClient封裝了client的邏輯和回調,比如connector。

2)muduo僅僅提供了3個最基礎的設施(事件處理,TimerQueue 和 functionQueue),并沒有提供像anet的timeout的機制,也沒有提供channelid。這些功能可以通過3個基礎設在muduo的上層實作。ppt最後一頁舉了個處理idle連結的例子。把所有的連結組織成8個boost::circle_buffer。并處理兩個事件:a)連結的建立,把conn的shared_ptr插入尾端;b)消息的到來,再一次把連結的shared_ptr再次插入尾端。同時,注冊一個定時器:每一秒往boost::circle_buffer尾部插入一個trival的結構,目的是每隔一秒淘汰首部的shared_ptr;當所有的格子裡的shared_ptr都淘汰之後,conn就被析構了。

3)性能展現在細節上。a)buffer的設計,muduo的buffer設計和anet如出一轍。b)read讀取資料,在棧上開64k的空間,使用readv,把目前conn的inputBuffer_和棧上開的空間組織一起,使用gatherIO。然後把棧上讀取到的資料copy到inputBuffer_。這樣既一次read調用可以盡量多的讀取資料,又不需要在inputBuffer預配置設定過多的空間。c)發送資料的時候,如果outputBuffer_上是空的,盡量直接發送出去,節省了outputBuffer_序列化的時間。這些實作都是基于muduo良好的基礎設施。d)多個IO線程,緩解關鍵線程的壓力。

4)多個IO處理線程。之前iSearch4的時候,1688的merger和searcher比例3:1,大部分是在收發資料,一個anet線程不能及時處理,因為IO線程并不是簡單的read,write。它還要負責packet的解析,上層應用的回調,這些都給關鍵的IO的線程帶來壓力。是以,面對萬兆網卡,或大吞吐量的應用,單個IO線程是吃力的。muduo的多IO線程的實作:1)中講到了EventLoop 隻是封裝了處理事件的邏輯,和執行體線程是解耦合的。開啟多IO線程時,開多個thread,每個thread綁定一個EventLoop。當一個連結建立之後,把這個連結路由給一個線程就可以了。

5)語言風格上。a)muduo大量使用了bind/function,這一對函數其實是在模仿‘閉包’的概念。把多線程并發做的事情,封裝成一個個的閉包,‘線性化’到EventLoop線程的functionQueue,同步化處理。使得在99%不需要鎖的地方,徹底無鎖了。犧牲的僅僅是一點點的串形化。同時,有了閉包,就不必到處繼承‘接口類’。是代碼也簡潔了一些。b)大量的使用了shared_ptr, weak_ptr管理資源,避免手工管理引用計數,像anet一樣。shared_ptr,weak_ptr的性能也很客觀,即使是頻繁的構造析構(當然,設計上能避免就避免構造析構。

《Muduo 多線程網絡庫解析》
《Muduo 多線程網絡庫解析》
《Muduo 多線程網絡庫解析》
《Muduo 多線程網絡庫解析》
《Muduo 多線程網絡庫解析》
《Muduo 多線程網絡庫解析》
《Muduo 多線程網絡庫解析》
《Muduo 多線程網絡庫解析》
《Muduo 多線程網絡庫解析》
《Muduo 多線程網絡庫解析》
《Muduo 多線程網絡庫解析》
《Muduo 多線程網絡庫解析》
《Muduo 多線程網絡庫解析》
《Muduo 多線程網絡庫解析》
《Muduo 多線程網絡庫解析》
《Muduo 多線程網絡庫解析》

繼續閱讀