libev與libuv的區別


參考:

http://blog.csdn.net/w616589292/article/details/46475555

 

libuv 和 libev ,兩個名字相當相近的 I/O Library,最近有幸用兩個 Library 都寫了一些東西,下面就來說一說我本人對兩者共同與不同點的主觀表述。

高性能網絡編程這個話題已經被討論爛了。異步,異步,還是異步。不管是 epoll 也好,kqueue 也罷,總是免不了異步這個話題。

libev 是系統異步模型的簡單封裝,基本上來說,它解決了 epoll ,kqueuq 與 select 之間 API 不同的問題。保證使用 livev 的 API 編寫出的程序可以在大多數 *nix 平台上運行。但是 libev 的缺點也是顯而易見,由於基本只是封裝了 Event Library,用起來有諸多不便。比如 accept(3) 連接以后需要手動 setnonblocking 。從 socket 讀寫時需要檢測 EAGAIN 、EWOULDBLOCK 和 EINTER 。這也是大多數人認為異步程序難寫的根本原因。

libuv 則顯得更為高層。libuv 是 joyent 給 Node 做的一套 I/O Library 。而這也導致了 libuv 最大的特點就是處處回調。基本上只要有可能阻塞的地方,libuv 都使用回調處理。這樣做實際上大大減輕了程序員的工作量。因為當回調被 call 的時候,libuv 保證你有事可做,這樣 EAGAIN 和 EWOULDBLOCK 之類的 handle 就不是程序員的工作了,libuv 會默默的幫你搞定。

libev 在 socket 發生讀寫事件時,只告訴你,“XX socket 可以讀/寫了,自己看着辦吧”。往往我們需要自己申請內存並調用 read(3) 或者 write(3) 來響應 I/O 事件。

libuv 則稍微復雜一些,我們分讀/寫兩個部分來描述。

當接口可讀時,libuv 會調用你的 allocate callback 來申請內存並將讀到的內容寫入。當讀取完畢后,libuv 會 call 你為這個 socket 設置的回調函數,在參數中帶着這個 buffer 的信息。你只需要負責處理這個 buffer 並且free 掉就OK了。因為是從 buffer 中讀取數據,在你的 callback 被調用時數據已經 ready 了,所以程序員也就不用考慮阻塞的問題了。

而對寫的處理則更顯巧妙。libuv 沒有 write callback ,如果你想寫東西,直接 generate 一個 write request 連着要寫的 buffer 一起丟給 libuv ,libuv 會把你的 write request 加進相應 socket 的 write queue ,在 I/O 可寫時按順序寫入。

C 沒有閉包,所以確定讀寫上下文是 libuv 的使用者需要面對的問題。否則程序面對洶涌而來的 buffer 也不能分得清哪個是哪個的數據。在這一點的處理上,libuv 跟 libev 一樣,都是使用了一個 void *data 來解決問題。你可以用 data 這個 member 存儲任何東西,這樣當 buffer 來的時候,只需要簡單的把 data cast 到你需要的類型就 OK 了。

libev 沒有異步 DNS 解析,這一點一直廣為垢病。

libuv 有異步的 DNS 解析,解析結果也是通過回調的方式通知程序。

libev 完全是單線程的。

libuv 需要多線程庫支持,因為其在內部維護了一個線程池來 handle 諸如 getaddrinfo(3) 這樣的無法異步的調用。

libev 貌似是作者一個人在開發,版本管理使用的還是 CVS ,社區參與度明顯不高。

libuv 社區十分活躍,幾乎每天都有人提出 Issue 並貢獻代碼。

libev 不支持 IOCP ,如果需要在 Win 下運行的程序會很麻煩。

libuv 支持 IOCP ,有相應腳本編譯 Win 下的庫。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM