I/O模型 与 select, iocp, epoll,kqueue

1,IO模型如下:

  • 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

 


当用户进程调用了recvfrom这个(system call)系统调用,kernel就开始了IO的第一个阶段:(wait for data)准备数据,在这时kernel要等待足够的数据到来(如对于network io来说,很多时候数据在一开始还没有到达,还没收到完整的UDP包),而在这过程对于用户进程是(blocking )阻塞的;当kernel一直等到数据准备好了,它就会将数据从kernel中拷贝到用户内存,然后kernel返回结果,用户进程才解除block的状态,重新运行起来。
所以,blocking IO的特点就是在IO执行的两个阶段都被block了

 

 

 

 

nonblocking I/O


 

可以看出,用户进程不断(polling)轮询 发出recvfrom,而如果kernel中的数据还没有准备好,那么它并不会block用户进程,而是立刻返回一个error。用户根据这error标识知道kernel中的数据还没有准备好,再次发出recvfrom 一旦kernel中的数据准备好了,并且又再次收到了用户进程的system call,那么它马上就将数据拷贝到了用户内存,然后返回。

 

 

 

I/O multiplexing (select and poll )
 

 

 

 

 


signal driven I/O (SIGIO)

 

 

 

 

 

 

 

asynchronous I/O (the POSIX aio_functions)


 

 

 

 

 


 
 各个IO Model的比较如图所示:

 


 

 

 

select, epoll,kqueue ,iocp 对应的模型如下

 

select  -> I/O multiplexing (select and poll )

 

epoll   -> epoll is a scalable I/O event notification mechanism for Linux ,

 

 

kqueue -> Kqueue is a scalable event notification interface introduced in FreeBSD 4.1

 

iocp -> asynchronous I/O (the POSIX aio_ functions)          windows(采用)

 

 

select, epoll,kqueue 都是属于同一模型,只不过是 epoll,kqueue解决了select的一些局限性,更加高级点

可以看作有了第4种模型的某些特性,如callback机制等

 

他们无轮询 。因为他们用callback取代了。想想 看,当套接字比较多的时候,每次select()都要通过遍历FD_SETSIZE个Socket来完成调度,不管哪个Socket是活跃的,都遍历一 遍。这会浪费很多CPU时间。如果能给套接字注册某个回调函数,当他们活跃时,自动完成相关操作,那就避免了轮询,这正是epoll与kqueue做的。

 

 

 

 

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服务器为什么效率还不错。。我也不得而知,可能是设计得比较好吧。。-_-。

=====================分割线==================================

总结一些重点:

  1. 只有IOCP是asynchronous I/O,其他机制或多或少都会有一点阻塞。
  2. select低效是因为每次它都需要轮询。但低效也是相对的,视情况而定,也可通过良好的设计改善
  3. epoll, kqueue是Reacor模式,IOCP是Proactor模式。
  4. java nio包是select模型。。

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值