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模型。。
相关推荐
介绍当前Windows支持的各种Socket I/O模型 select WSAAsyncSelect WSAEventSelect Overlapped I/O(重叠IO模型),IOCP模型,有代码详细分析过程
利用Visual C++ 6.0实现的一套Winsock I/O模型,包括了所有的Winsock I/O模型:Select模型、AsyncSelect(异步选择模型)、EventSelect(事件选择模型)、Overlapped(重叠模型)、CompletionRoutine(完成例程)、...
关于epoll iocp select等网络模型运行实例代码
IOCP全称I/O Completion Port,中文译为I/O完成端口。IOCP是一个异步I/O的API,它可以高效地将I/O事件通知给应用程序。与使用select()或是其它异步方法不同的是,一个套接字[socket]与一个完成端口关联了起来,然后...
iocp-epoll的几个例子,提供参考。 其中,iocp包含了几种使用方式,同步异步处理方式, epoll为linux下面使用,编译时可以使用下面简单命令, g++ -p -g -o hhh ***.cpp -l pthread
IOCP是一个异步I/O的API,它可以高效地将I/O事件通知给应用程序。与使用select()或是其它异步方法不同的是,一个套接字[socket]与一个完成端口关联了起来,然后就可继续进行正常的Winsock操作了。然而,当一个事件...
miow文档一个零开销的Windows I / O库,重点放在IOCP和其他异步I / O功能上。 #Cargo.toml [dependencies] miow =“ 0.3”许可证miow文档集中于IOCP和其他异步I / O功能的零开销Windows I / O库。 #Cargo.toml ...
IOCP全称I/O Completion Port,中文译为I/O完成端口。IOCP是一个异步I/O的API,它可以高效地将I/O事件通知给应用程序。
windows下六种socket I/O模型示例,例子很详细地描绘出各种模式的用法,适合windows下网络编程的人
Linux / FreeBSD / Windows的高性能协同库,支持select / poll / epoll / kqueue / iocp / windows GUI
基于C++的iopc,连接SOCKet多线程“完成端口”IOCP全称I/O Completion Port,中文译为I/O完成端口。IOCP是一个异步I/O的API,它可以高效地将I/O事件通知给应用程序。与使用select()或是其它异步方法不同的是,...
由 epoll、kqueue、IOCP、事件端口支持的全功能事件循环。异步 TCP 和 UDP 套接字。异步 DNS 解析。异步文件和文件系统操作。文件系统事件。ANSI 转义码控制的 TTY。具有套接字共享功能的 IPC,使用 Unix 域套接字或...
IOCP(I/O Completion Port,I/O完成端口)是性能最好的一种I/O模型。它是应用程序使用线程池处理异步I/O请求的一种机制。在处理多个并发的异步I/O请求时,以往的模型都是在接收请求是创建一个线程来应答请求。这样...
对SOCKET的I/O模式进行代码级分析 并进行性能差异比较
kuma在Linux / Windows / OSX / iOS / Android平台上支持epoll / poll / WSAPoll / IOCP / kqueue / select。产品特点支持epoll,poll / WSAPoll,IOCP,kqueue和选择便携式/跨平台(Linux,Windows,macOS,iOS和...
libevent 轻量级的开源高性能事件通知库,支持多种 I/O 多路复用技术,内部使用select、epoll、kqueue、IOCP等系统调用管理事件机制。 支持 I/O,定时器和信号等事件,支持注册事件优先级。可用来构建http服务端、...
新手学习iocp的好例子~MFC下的完成端口IOCP源码学习线程池与完成端口的朋友可参考参考
linux下的epoll模拟IOCP异步的demo,希望对学习epoll的朋友有所帮助。
老外的iocp代码。感觉非常好,文章见如下 http://blog.csdn.net/weicaijiang/article/details/77529163
使用libevent库设置httpserver所使用的系统特征值(select、epoll、iocp等)