blocking I/Ohtml
nonblocking I/Ojava
I/O multiplexing (select and poll)react
signal driven I/O (SIGIO)linux
asynchronous I/O (the POSIX aio_functions)—————异步IO模型最大的特色是 完成后发回通知。编程
阻塞与否,取决于实现IO交换的方式。windows
异步阻塞是基于select,select函数自己的实现方式是阻塞的,而采用select函数有个好处就是它能够同时监听多个文件句柄.设计模式
异步非阻塞直接在完成后通知,用户进程只须要发起一个IO操做而后当即返回,等IO操做真正的完成之后,应用程序会获得IO操做完成的通知,此时用户进程只须要对数据进行处理就行了,不须要进行实际的IO读写操做,由于真正的IO读取或者写入操做已经由内核完成了。数组
这个不用多解释吧,阻塞套接字。下图是它调用过程的图示:服务器
重点解释下上图,下面例子都会讲到。首先application调用 recvfrom()转入kernel,注意kernel有2个过程,wait for data和copy data from kernel to user。直到最后copy complete后,recvfrom()才返回。此过程一直是阻塞的。网络
与blocking I/O对立的,非阻塞套接字,调用过程图以下:
能够看见,若是直接操做它,那就是个轮询。。直到内核缓冲区有数据。
最多见的I/O复用模型,select。
select先阻塞,有活动套接字才返回。与blocking I/O相比,select会有两次系统调用,可是select能处理多个套接字。
只有UNIX系统支持,感兴趣的课查阅相关资料
与I/O multiplexing (select and poll)相比,它的优点是,免去了select的阻塞与轮询,当有活跃套接字时,由注册的handler处理。
不多有*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机制。
答案是,他们无轮询。由于他们用callback取代了。想一想看,当套接字比较多的时候,每次select()都要经过遍历FD_SETSIZE个Socket来完成调度,无论哪一个Socket是活跃的,都遍历一遍。这会浪费不少CPU时间。若是能给套接字注册某个回调函数,当他们活跃时,自动完成相关操做,那就避免了轮询,这正是epoll与kqueue作的。
诚然,Windows的IOCP很是出色,目前不多有支持asynchronous I/O的系统,可是因为其系统自己的局限性,大型服务器仍是在UNIX下。并且正如上面所述,kqueue/epoll 与 IOCP相比,就是多了一层从内核copy数据到应用层的阻塞,从而不能算做asynchronous I/O类。可是,这层小小的阻塞无足轻重,kqueue与epoll已经作得很优秀了。
实际上,无论是哪一种模型,均可以抽象一层出来,提供一致的接口,广为人知的有ACE,Libevent(基于reactor模式)这些,他们都是跨平台的,并且他们自动选择最优的I/O复用机制,用户只需调用接口便可。说到这里又得说说2个设计模式,Reactor and Proactor。见:Reactor模式--VS--Proactor模式。Libevent是Reactor模型,ACE提供Proactor模型。实际都是对各类I/O复用机制的封装。
如今能够肯定,目前的java本质是select()模型,能够检查/jre/bin/nio.dll得知。至于java服务器为何效率还不错。。我也不得而知,多是设计得比较好吧。。-_-。
=====================分割线==================================
1. 使用多进程或者多线程,可是这种方法会形成程序的复杂,并且对与进程与线程的建立维护也须要不少的开销。(Apache服务器是用的子进程的方式,优势能够隔离用户) (同步阻塞IO)
2.一种较好的方式为I/O多路转接(I/O multiplexing)(貌似也翻译多路复用),先构造一张有关描述符的列表(epoll中为队列),而后调用一个函数,直到这些描述符中的一个准备好时才返回,返回时告诉进程哪些I/O就绪。select和epoll这两个机制都是多路I/O机制的解决方案,select为POSIX标准中的,而epoll为Linux所特有的。
1.select的句柄数目受限,在linux/posix_types.h头文件有这样的声明:#define __FD_SETSIZE 1024 表示select最多同时监听1024个fd。而epoll没有,它的限制是最大的打开文件句柄数目。
2.epoll的最大好处是不会随着FD的数目增加而下降效率,在selec中采用轮询处理,其中的数据结构相似一个数组的数据结构,而epoll是维护一个队列,直接看队列是否是空就能够了。epoll只会对"活跃"的socket进行操做---这是由于在内核实现中epoll是根据每一个fd上面的callback函数实现的。那么,只有"活跃"的socket才会主动的去调用 callback函数(把这个句柄加入队列),其余idle状态句柄则不会,在这点上,epoll实现了一个"伪"AIO。可是若是绝大部分的I/O都是“活跃的”,每一个I/O端口使用率很高的话,epoll效率不必定比select高(多是要维护队列复杂)。
3.使用mmap加速内核与用户空间的消息传递。不管是select,poll仍是epoll都须要内核把FD消息通知给用户空间,如何避免没必要要的内存拷贝就很重要,在这点上,epoll是经过内核于用户空间mmap同一块内存实现的。
epoll有两种工做方式
ET:Edge Triggered,边缘触发。仅当状态发生变化时才会通知,epoll_wait返回。换句话,就是对于一个事件,只通知一次。且只支持非阻塞的socket。
LT:Level Triggered,电平触发(默认工做方式)。相似select/poll,只要还有没有处理的事件就会一直通知,以LT方式调用epoll接口的时候,它就至关于一个速度比较快的poll.支持阻塞和不阻塞的socket。
1 Apache 模型,简称 PPC ( Process Per Connection ,):为每一个链接分配一个进程。主机分配给每一个链接的时间和空间上代价较大,而且随着链接的增多,大量进程间切换开销也增加了。很难应对大量的客户并发链接。
2 TPC 模型( Thread Per Connection ):每一个链接一个线程。和PCC相似。
3 select 模型:I/O多路复用技术。
.1 每一个链接对应一个描述。select模型受限于 FD_SETSIZE即进程最大打开的描述符数linux2.6.35为1024,实际上linux每一个进程所能打开描数字的个数仅受限于内存大小,然而在设计select的系统调用时,倒是参考FD_SETSIZE的值。可经过从新编译内核更改此值,但不能根治此问题,对于百万级的用户链接请求 即使增长相应 进程数, 仍显得杯水车薪呀。
.2select每次都会扫描一个文件描述符的集合,这个集合的大小是做为select第一个参数传入的值。可是每一个进程所能打开文件描述符如果增长了 ,扫描的效率也将减少。
.3内核到用户空间,采用内存复制传递文件描述上发生的信息。
4 poll 模型:I/O多路复用技术。poll模型将不会受限于FD_SETSIZE,由于内核所扫描的文件 描述符集合的大小是由用户指定的,即poll的第二个参数。但仍有扫描效率和内存拷贝问题。
5 pselect模型:I/O多路复用技术。同select。
6 epoll模型:
.1)无文件描述字大小限制仅与内存大小相关
.2)epoll返回时已经明确的知道哪一个socket fd发生了什么事件,不用像select那样再一个个比对。
.3)内核到用户空间采用共享内存方式,传递消息。
一、单个epoll并不能解决全部问题,特别是你的每一个操做都比较费时的时候,由于epoll是串行处理的。 因此你有仍是必要创建线程池来发挥更大的效能。
二、若是fd被注册到两个epoll中时,若是有时间发生则两个epoll都会触发事件。
三、若是注册到epoll中的fd被关闭,则其会自动被清除出epoll监听列表。
四、若是多个事件同时触发epoll,则多个事件会被联合在一块儿返回。
五、epoll_wait会一直监听epollhup事件发生,因此其不须要添加到events中。
六、为了不大数据量io时,et模式下只处理一个fd,其余fd被饿死的状况发生。linux建议能够在fd联系到的结构中增长ready位,而后epoll_wait触发事件以后仅将其置位为ready模式,而后在下边轮询ready fd列表。
参考:
http://blog.csdn.net/ysu108/article/details/7570571
http://techbbs.zol.com.cn/1/8_2245.html
转自:http://blog.csdn.net/wenbingoon/article/details/9004512