Libevent、libev、libuv三個網絡庫,都是c語言實現的異步事件庫Asynchronousevent library)。node
異步事件庫本質上是提供異步事件通知(Asynchronous Event Notification,AEN)的。異步事件通知機制就是根據發生的事件,調用相應的回調函數進行處理。linux
事件(Event):事件是異步事件通知機制的核心,好比fd事件、超時事件、信號事件、定時器事件。有時候也稱事件爲事件處理器(EventHandler),這個名稱更形象,由於Handler自己表示了包含處理所需數據(或數據的地址)和處理的方法(回調函數),更像是面向對象思想中的稱謂。git
事件循環(EventLoop):等待並分發事件。事件循環用於管理事件。github
對於應用程序來講,這些只是異步事件庫提供的API,封裝了異步事件庫跟操做系統的交互,異步事件庫會選擇一種操做系統提供的機制來實現某一種事件,好比利用Unix/Linux平臺的epoll機制實現網絡IO事件,在同時存在多種機制能夠利用時,異步事件庫會採用最優機制。windows
libevent :名氣最大,應用最普遍,歷史悠久的跨平臺事件庫;緩存
libev :較libevent而言,設計更簡練,性能更好,但對Windows支持不夠好;安全
libuv :開發node的過程當中須要一個跨平臺的事件庫,他們首選了libev,但又要支持Windows,故從新封裝了一套,linux下用libev實現,Windows下用IOCP實現;網絡
可見,目前libuv的影響力最大,其次是libevent,libev關注的人較少。架構
特性異步 |
libevent |
libev |
libuv |
優先級 |
激活的事件組織在優先級隊列中,各種事 件默認的優先級是相同的,能夠經過設置 事件的優先級使其優先被處理 |
也是經過優先級隊列來管理激活的時間, 也能夠設置事件優先級 |
沒有優先級概念,按照固定的順序訪 問各種事件 |
事件循環 |
event_base用於管理事件 |
激活的事件組織在優先級隊列中,各種事件默認的優先級是相同的, 能夠通 過設置事件的優先級 使其優先被處理 |
|
線程安全 |
event_base和loop都不是線程安全的,一個event_base或loop實例只能在用戶的一個線程內訪問(通常是主線程),註冊到event_base或者loop的event都是串行訪問的,即每一個執行過程當中,會按照優先級順序訪問已經激活的事件,執行其回調函數。因此在僅使用一個event_base或loop的狀況下,回調函數的執行不存在並行關係
|
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
type |
libevent |
libev |
libuv |
dev/poll (Solaris) |
y |
y |
y |
event ports |
y |
y |
y |
kqueue (*BSD) |
y |
y |
y |
POSIX select |
y |
y |
y |
Windows select |
y |
y |
y |
Windows IOCP |
y |
N |
y |
poll |
y |
y |
y |
epoll |
y |
y |
y |
對於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。