select, iocp, epoll,kqueue及各种I/O复用机制
首先,介绍几种常见的I/O模型及其区别,如下:
-
blocking I/O
-
nonblocking I/O
-
I/O multiplexing (select and poll)
-
signal driven I/O (SIGIO)
-
asynchronous I/O (the POSIX aio_functions)
blocking I/O
这个不用多解释吧,阻塞套接字。下图是它调用过程的图示:
重 点解释下上图,下面例子都会讲到。首先application调用 recvfrom()转入kernel,注意kernel有2个过程,wait for data和copy data from kernel to user。直到最后copy complete后,recvfrom()才返回。此过程一直是阻塞的。
nonblocking I/O:
与blocking I/O对立的,非阻塞套接字,调用过程图如下:
可以看见,如果直接操作它,那就是个轮询。。直到内核缓冲区有数据。
I/O multiplexing (select and poll)
最常见的I/O复用模型,select。
select先阻塞,有活动套接字才返回。与blocking I/O相比,select会有两次系统调用,但是select能处理多个套接字。
signal driven I/O (SIGIO)
只有UNIX系统支持,感兴趣的课查阅相关资料
与I/O multiplexing (select and poll)相比,它的优势是,免去了select的阻塞与轮询,当有活跃套接字时,由注册的handler处理。
asynchronous I/O (the POSIX aio_functions)
很少有*nix系统支持,windows的IOCP则是此模型
完全异步的I/O复用机制,因为纵观上面其它四种模型,至少都会在由kernel copy data to appliction时阻塞。而该模型是当copy完成后才通知application,可见是纯异步的。好像只有windows的完成端口是这个模型,效率也很出色。
下面是以上五种模型的比较
可以看出,越往后,阻塞越少,理论上效率也是最优。
=====================分割线==================================
5种模型的比较比较清晰了,剩下的就是把select,epoll,iocp,kqueue按号入座那就OK了。
select和iocp分别对应第3种与第5种模型,那么epoll与kqueue呢?其实也于select属于同一种模型,只是更高级一些,可以看作有了第4种模型的某些特性,如callback机制。
那么,为什么epoll,kqueue比select高级?
答案是,他们无轮询。 因为他们用callback取代了。想想看,当套接字比较多的时候,每次select()都要通过遍历FD_SETSIZE个Socket来完成调度,不 管哪个Socket是活跃的,都遍历一遍。这会浪费很多CPU时间。如果能给套接字注册某个回调函数,当他们活跃时,自动完成相关操作,那就避免了轮询, 这正是epoll与kqueue做的。
windows or *nix (IOCP or kqueue/epoll)?
诚然,Windows的IOCP非常出色,目前很少有支持asynchronous I/O的系统,但是由于其系统本身的局限性,大型服务器还是在UNIX下。而且正如上面所述,kqueue/epoll 与 IOCP相比,就是多了一层从内核copy数据到应用层的阻塞,从而不能算作asynchronous I/O类。但是,这层小小的阻塞无足轻重,kqueue与epoll已经做得很优秀了。
提供一致的接口,IO Design Patterns
实际上,不管是哪种模型,都可以抽象一层出来,提供一致的接口,广为人知的有ACE,Libevent这些,他们都是跨平台的,而且他们自动选择最优的I/O复用机制,用户只需调用接口即可。说到这里又得说说2个设计模式,Reactor and Proactor。有一篇经典文章http://www.artima.com/articles/io_design_patterns.html值得阅读,Libevent是Reactor模型,ACE提供Proactor模型。实际都是对各种I/O复用机制的封装。
Java nio包是什么I/O机制?
我曾天真的认为java nio封装的是IOCP。。现在可以确定,目前的java本质是select()模型,可以检查/jre/bin/nio.dll得知。至于java服务器为什么效率还不错。。我也不得而知,可能是设计得比较好吧。。-_-。
=====================分割线==================================
总结一些重点:
- 只有IOCP是asynchronous I/O,其他机制或多或少都会有一点阻塞。
- select低效是因为每次它都需要轮询。但低效也是相对的,视情况而定,也可通过良好的设计改善
- epoll, kqueue是Reacor模式,IOCP是Proactor模式。
- java nio包是select模型。。
相关推荐
- **I/O复用**:通过`select`、`poll`、`epoll`(Linux)或`kqueue`(FreeBSD)等函数,应用可以监控多个socket,当它们准备就绪时,系统会通知。I/O复用模型适合处理大量并发连接,特别是服务器场景。 - **信号...
《深入理解libevent-1.4.4-iocp-3:事件驱动编程与I/O复用技术的应用》 在IT行业中,事件驱动编程和I/O复用技术是构建高性能网络服务的关键技术之一。libevent是一个广泛使用的开源库,它为开发者提供了在多种操作...
总结来说,epoll作为Linux下的IO复用机制,相比select和poll,具备更好的性能和扩展性,尤其适用于处理高并发的网络应用。它的设计使得在处理大量并发连接时,能显著减少系统调用次数,提高程序运行效率,是现代网络...
libevent 是轻量级的开源高性能事件通知库,支持多种 I/O 多路复用技术,内部使用select、epoll、kqueue、IOCP等系统调用管理事件机制。 支持超时事件、持久事件, I/O事件,定时器和信号等事件,支持注册事件优先级...
本文将深入探讨一款名为"libfiber"的高性能协同库,它为Linux、FreeBSD以及Windows操作系统提供了强大的异步I/O和多路复用技术,包括select、poll、epoll、kqueue和iocp等。 首先,让我们理解一下协同库的核心价值...
1. **Linux Epoll**: Epoll是Linux内核提供的一种I/O多路复用技术,它是select和poll的升级版。Epoll的优点在于它可以避免大量文件描述符时的性能问题,并且支持边缘触发(ET)和水平触发(LT)两种模式,提供了更...
在类unix系统中有五大I/O模型,依次为阻塞IO(BIO)、非阻塞IO(NIO)、IO多路复用(linux下有select、poll、epoll三种方案)、信号驱动IO、异步IO(前面四种都是同步IO),本文主要介绍常用的C的IO库,几乎都是...
3. **Unix**:Unix系统通常使用select、poll和kqueue等机制来处理多路复用IO。 五、IO管理器的优化策略 1. **零拷贝**:通过避免数据在用户空间和内核空间之间多次拷贝,提高IO性能。 2. **预读取和延迟写入**:...
2. 使用更高效的I/O多路复用技术,如select、poll、epoll或kqueue,以减少系统调用的开销。 【调度】 调度在协程中扮演着关键角色,因为它决定了何时以及如何在不同协程之间切换。在传统的多线程环境中,调度通常是...
8. **多路复用技术**:Boost.Asio支持多种I/O多路复用技术,如POSIX的epoll、kqueue和select,以及Windows的IOCP。 9. **对象所有权和生命周期管理**:理解何时和如何正确管理Boost.Asio对象的生命周期是避免内存...
此外,Windows还提供了高级的网络功能,如套接字选项(setsockopt/getsockopt)、多路复用(select/poll/epoll/kqueue等)和套接字级广播或多播。这些特性可以用于优化性能,处理复杂网络场景,比如心跳检测、超时重...