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 吞吐量对比