Libevent,libuv,libev,IOCP,asio,muduo,tbnet,epoll/select/poll 是什麼?C10K是什麼?
在研究服務端程序併發能力時看到這些詞彙,本文簡單記錄記錄,作爲日後細看這些東西的的導引。
1. epoll/select/poll 是IO複用模型
- 如果一個請求就創建一個進程的話,進程佔用資源多,單機負載能力不行,於是就有了一個進程來處理多個請求的方法,也就是IO複用,目前的常用的IO複用模型有三種:select,poll,epoll。
- poll 和 select 的實現非常類似,本質上的區別就是存放 fd 集合的數據結構不一樣。select 在一個進程內可以維持最多 1024 個連接,poll 在此基礎上做了加強,可以維持任意數量的連接。
- epoll是基於內核的反射機制,在有活躍的 socket 時,系統會調用我們提前設置的回調函數。而 poll 和 select 都是遍歷(輪訓,如果持有較多數量的鏈接,如一百萬個,性能會比較差)。
2. Libevent,libuv,libev,IOCP,asio,muduo,tbnet都是網絡函數庫
-
Libevent、libev、libuv三個網絡庫,都是C語言實現的異步事件庫(Asynchronousevent library),異步事件通知機制就是根據發生的事件,調用相應的回調函數進行處理。
-
對比下三個庫:
-
libevent :名氣最大,應用最廣泛,歷史悠久的跨平臺事件庫;
-
libev :較libevent而言,設計更簡練,性能更好,但對Windows支持不夠好;
-
libuv :開發node的過程中需要一個跨平臺的事件庫,他們首選了libev,但又要支持Windows,故重新封裝了一套,linux下用libev實現,Windows下用IOCP實現;
-
-
康康github上的start感覺感覺他們的影響力 (libuv >> libevent > libev):
- https://github.com/libevent/libevent
- https://github.com/enki/libev
- https://github.com/libuv/libuv
-
優先級、事件循環、線程安全維度的對比
-
事件種類
type | libevent | libev | libuv |
---|---|---|---|
IO | fd | io | fs_event |
計時器 (mono clock) | timer | timer | timter |
計時器(wall clock) | – | periodic | – |
信號 | signal | signal | signal |
進程控制 | – | child | process |
文件stat | – | stat | fs_poll |
每次循環都會執行的Idle事件 | – | idle | idle |
循環block之前執行 | – | prepare | prepare |
循環blcck之後執行 | – | check | check |
嵌套loop | – | embed | – |
fork | – | fork | – |
loop銷燬之前的清理工作 | – | cleanup | – |
操作另一個線程中的loop | – | async | async |
stream ( tcp, pipe, tty ) | stream ( tcp, pipe, tty ) | stream ( tcp, pipe, tty ) | stream ( tcp, pipe, tty ) |
這個對比對於libev和libuv更有意義,對於libevent,很多都是跟其設計思想有關的。 libev中的embed很少用,libuv沒有也沒關係;cleanup完全可以用libuv中的async_exit來替代;libuv沒有fork事件。
-
可移植性:
- 三個庫都支持Linux, *BSD, Mac OS X, Solaris, Windows
- 對於Unix/Linux平臺,沒有什麼大不同,優先選擇epoll,對於windows,libevent、libev都使用select檢測和分發事件(不I/O),libuv在windows下使用IOCP。libevent有一個socket handle, 在windows上使用IOCP進行讀寫。libev沒有類似的。但是libevent的IOCP支持也不是很好(性能不高)。所以如果是在windows平臺下,使用原生的IOCP進行I/O,或者使用libuv。
-
IOCP是windows下IO事件處理的最高效的一種方式,結合OVERLAPPED IO可以實現真正的完全異步IO。不支持跨平臺。
-
boost::asio,C++語言跨平臺。用bind做回調也並不比虛函數好,看上去靈活了,代價卻更高了。不光是運行時的內存和時間代價,編譯時間也更長。基於ASIO開發應用,要求程序員熟悉函數對象,函數指針,熟悉boost庫中的boost::bind,內存管理控制方面。
-
asio是一個高性能的網絡開發庫,Windows下使用IOCP,Linux下使用epoll。
-
Muduo是一個用純c++寫的庫,僅在linux下使用,one loop per thread的思想貫穿其中,將I/O 定時 信號都通過文件描述符的方式融合在一起,三類事件等同於一類事件來看待。
-
有文章對比說muduo比libevent2吞吐量高不少。
-
tbnet是淘寶開源的網絡通訊庫,底層是epoll和EventLoop。
參考文獻:
[1] Libevent文檔
[2] select、poll、epoll之間的區別
[3] libevent、libev、libuv、IOCP、asio、muduo優劣分析、QT下編譯libevent靜態庫
[4] 一次讀懂 Select、Poll、Epoll IO複用技術
[5] muduo 與 libevent2 吞吐量對比