libuv和libev 异步I/O库的比较
libuv 和 libev ,两个名字相当相近的 I/O Library,最近有幸用两个 Library 都写了一些东西,下面就来说一说我本人对两者共同与不同点的主观表述。
高性能网络编程这个话题已经被讨论烂了。异步,异步,还是异步。不管是 epoll 也好,kqueue 也罢,总是免不了异步这个话题。
1.使用:
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 会默默的帮你搞定。
2.读写事件
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 了。
3.DNS解析
libev 没有异步 DNS 解析,这一点一直广为垢病。
libuv 有异步的 DNS 解析,解析结果也是通过回调的方式通知程序。
4.多线程
libev 完全是单线程的。
libuv 需要多线程库支持,因为其在内部维护了一个线程池来 handle 诸如 getaddrinfo(3) 这样的无法异步的调用。
5.IOCP
libev 不支持 IOCP ,如果需要在 Win 下运行的程序会很麻烦。
libuv 支持 IOCP ,有相应脚本编译 Win 下的库。
6.社区
libev 貌似是作者一个人在开发,版本管理使用的还是 CVS ,社区参与度明显不高。
libuv 社区十分活跃,几乎每天都有人提出 Issue 并贡献代码。
原文:http://blog.csdn.net/w616589292/article/details/46475555
http://www.cnblogs.com/ningskyer/articles/5879503.html
---------------------------------------------------------------------------------------------------------
05 January 2013
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
libuv和libev 异步I/O库的比较的更多相关文章
- libuv 与 libev 的对比
libuv 与 libev 的对比 libuv 与 libev 的对比 05 January 2013 libuv 和 libev ,两个名字相当相近的 I/O Library,最近有幸用两个 Lib ...
- 异步流程控制库GoWithTheFlow
异步流程控制库GoWithTheFlow 一个尾触发方式来控制异步流程的库, 有seq(顺序执行) par(同步执行) 两种方法 博客 http://notes.jetienne.com/2011/0 ...
- (源代码分析)Android-Universal-Image-Loader (图片异步载入缓存库)的使用配置
转载请注明出处:http://blog.csdn.net/u011733020 前言: 在Android开发中,对于图片的载入能够说是个老生常谈的问题了,图片载入是一个比較坑的地方.处理不好,会有各种 ...
- Jetpack Compose学习(4)——Image(图片)使用及Coil图片异步加载库使用
原文地址 Jetpack Compose学习(4)--Image(图片)使用及Coil图片异步加载库使用 | Stars-One的杂货小窝 本篇讲解下关于Image的使用及使用Coil开源库异步加载网 ...
- 一个高性能异步socket封装库的实现思路 (c#)
前言 socket是软件之间通讯最常用的一种方式.c#实现socket通讯有很多中方法,其中效率最高就是异步通讯. 异步通讯实际是利用windows完成端口(IOCP)来处理的,关于完成端口实现原理, ...
- python 异步MySQL存库
对于异步框架而言,这些延迟是无法接受的.因此, Twisted 提供了 twisted.enterprise.adbapi, 遵循DB-API 2.0协议的一个异步封装. adbapi 在单独的线程里 ...
- 异步请求Python库 grequests的应用和与requests库的响应速度的比较
requests库是python一个优秀的HTTP库,使用它可以非常简单地执行HTTP的各种操作,例如GET.POST等.不过,这个库所执行的网络请求都是同步了,即cpu发出请求指令后,IO执行发送和 ...
- Orace开源的异步IO编程库,特点是接口非常简单
官网:https://oss.oracle.com/projects/libaio-oracle/,正如标题所说,非常简单了,不用多解释,请直接看头文件,其中aio_poll类似于poll,重要的结构 ...
- Asp.net Core 入门实战 2.请求流程
Asp.Net Core 是开源,跨平台,模块化,快速而简单的Web框架. Asp.net Core官网的一个源码合集,方便一次性Clone,喜欢的(Star),本系列持续更新,也可以通过我的网站访问 ...
随机推荐
- perl对比两个文件的行
perl对比两个文件的行 对比两个文件的各行,得到A与B相同的行/A与B不相同的行 主要功能 得到相同行 得到A中包含,B不包含的行 得到B中包含,A中不包含的行 具体执行情况 Perl代码 #!/u ...
- Sphinx+MySQL5.1x+SphinxSE+mmseg中文分词
什么是Sphinx Sphinx 是一个全文检索引擎,一般而言,Sphinx是一个独立的搜索引擎,意图为其它应用提供快速.低空间占用.高结果相关度的全文搜索功能.Sphinx能够很easy的与SQL数 ...
- iconv简介(1、字符串|文件字符转换:iconv用于将一种已知的字符集文件转换成另一种已知的字符集文件)(2、编程语言函数功能的相似性:iconv不仅再php中有用,而且c语言中也有用,还有linux等)
iconv简介(1.字符串|文件字符转换:iconv用于将一种已知的字符集文件转换成另一种已知的字符集文件)(2.编程语言函数功能的相似性:iconv不仅再php中有用,而且c语言中也有用,还有lin ...
- dmalloc在嵌入式的开发板上的应用
下面是我实际在开发环境里面做的dmalloc移植时候的一些随笔 配置PC的dmalloc环境1. 首先把源码包打开,进入dmalloc文件夹2. ./configure 配置Makefile,我是加了 ...
- mysql查询字段所在表
use information_schema;select * from columns where column_name='字段名' ;
- css 父div如何包裹带有float属性的子div,float子div如何撑开父div
来自网络摘抄 原始代码 <style> #div1{border:1px solid red;float:left;} #div2,#div3{float:right;border:1px ...
- 【SSH2(理论+实践)】--图说Struts2的执行
前几篇文章讨论了有关Struts2的核心机制及一些基础,但同一时候也遗留下了非常多问题.这些问题主要是针对Struts2的一些使用技巧的,该篇文章将会针对Struts2的使用技巧进行讨论, ...
- html5常用标签table表格布局
html5常用标签table表格布局 一.总结 一句话总结: 二.html5常用标签table表格布局 用表格显示信息调理清楚,使浏览者一目了然.表格在网页中还有协助布局的作用,可以把文字.图像等组织 ...
- sqlplus中登陆账户用@加上数据库sid
sqlplus连接数据库时除了先输入用户名再输入密码的方式还有一种直接输入方式,而且使用@sid区分数据库,在有多个数据库时可方便区分 connect sys/sysdb@oraclesid as s ...
- JDBC连接数据库中CallableStatement执行有参存储过程及注解其他
Oracle的建有参存储过程的过程 procedure pro_01(v_01 in number,v_02 out varchar2) as begin select name into v_02 ...