libuv 和 libev ,两个名字至关相近的 I/O Library,最近有幸用两个 Library 都写了一些东西,下面就来讲一说我本人对二者共同与不一样点的主观表述。html
高性能网络编程这个话题已经被讨论烂了。异步,异步,仍是异步。不论是 epoll
也好,kqueue
也罢,老是免不了异步这个话题。git
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
会默默的帮你搞定。github
libev 在 socket 发生读写事件时,只告诉你,“XX socket 能够读/写了,本身看着办吧”。每每咱们须要本身申请内存并调用 read(3)
或者 write(3)
来响应 I/O 事件。编程
libuv 则稍微复杂一些,咱们分读/写两个部分来描述。c#
当接口可读时,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 不支持 IOCP
,若是须要在 Win 下运行的程序会很麻烦。
libuv 支持 IOCP
,有相应脚本编译 Win 下的库。
libev 貌似是做者一我的在开发,版本管理使用的仍是 CVS ,社区参与度明显不高。
libuv 社区十分活跃,几乎天天都有人提出 Issue 并贡献代码。
原文:http://blog.csdn.net/w616589292/article/details/46475555
http://www.cnblogs.com/ningskyer/articles/5879503.html
---------------------------------------------------------------------------------------------------------
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 下的库。
-----------------------------------------------------------------------------------
Q: 博主有没作过二者的benchmark,他们以前的性能对好比何?
A: 当时用 libev 和 libuv 写过一个简单的 HTTP Hello World Server 。具体结果记不清楚了可是能够说性能差距在 5% 之内。
Q: libuv 在 unix 上应该是用 libev 做为 non-blocking IO 的实现的吧?libuv 中线程池里线程的数量会增长么,是否会有上限?若是上限到了是否是就会出现 block 的状况?
A: 1. libuv 在大概5个月前已经彻底不使用 libev 了,参见 commit 665a316aa9d551ffdd00d1192d0c3d9c88d7e866 ; 2. libuv 的线程池在BSS上,数量固定为4个,参见:https://github.com/joyent/libuv/blob/master/src/unix/threadpool.c#L28 ; 3. libuv 的线程池共享一个work queue ,因此不会出现 block 的状况
https://my.oschina.net/jacobin/blog/146735