IO模型总结

咱们常说的IO模型主要是从Unix上拓展而来,因此提到IO模型通常都只是Unix下的IO模型,Unix下有5种可用的IO模型:linux

  • 阻塞式IO
  • 非阻塞式IO
  • IO复用
  • 信号驱动IO
  • 异步IO

除了【异步IO】之外,其余所有是同步IO,下面咱们就每一个概念详细说一下。编程

一、阻塞式IO数组

recvfrom 是系统调用,除非有数据返回或者发生错误才会返回,最多见错误就是信号中断,进程在调用recvfrom一直到它返回数据这段时间都是被阻塞的。安全

二、非阻塞IO模型网络

进程把一个套接字设置成非阻塞是在通知内核:当全部请求IO操做必需要把本进程投入睡眠才能完成的时候,不要把本进程投入睡眠,而是返回一个错误。异步

当一个应用进程对一个非阻塞进程进行循环调用的recvfrom的时候,咱们称之为轮询(polling),这样的模型每每会消耗大量的cpu。socket

三、I/O复用模型函数

IO多路复用指的是单个线程经过追踪管理每一个IO流的状态来同时管理多个IO流。性能

select poll epoll是IO多路复用的多个具体实现,之因此有三个实现是有前后顺序的。线程

select

  • select是最初实现的IO多路复用,select主要有如下问题
  • select会修改传入的参数数组,这个对一个会调用不少次的函数很不友好。
  • select中若是一个socketIO出现了数据,那么select会返回可是不会告诉你是那个socket上有数据,须要你本身去轮询,若是数量大,开销也会变大。
  • select只能监视1024个连接,这个跟linux系统参数有关系。
  • select不是线程安全的,例如一个socket被加入select,另一个线程又要关闭socket,那么select是不支持的,会发生没法预知的错误。

poll

poll修复了select大部分问题,例如再也不修改入参数组,去除了1024个连接的限制,可是poll仍然不是线程安全的,这会致使你仍是只能在一个线程里处理一组io,而不是多个线程来处理一组IO。

epoll

epoll是IO复用的最新实现,epoll修复了poll和select的绝大部分问题,而且提高了很是高的效率,例如:

  • epoll是线程安全的
  • epoll不只会返回数据,并且还会告诉你是哪一个socket有数据。

epoll缺点是只支持linux,在BSD中对应实现的是kqueue

性能对比:

能够看出epoll相对于select 和poll不会随着连接的增多而出现性能上的大幅度降低。

 

四、信号驱动IO模型

这种模型是在套接字中设置一个信号驱动函数,当第一次请求数据的时候会马上返回。当数据准备完毕的时候,内核会为这个进程产生一个信号,就会调用一开始进程内的驱动函数,在函数中咱们能够完成数据的复制处理,这种模式的优点在于在等待的期间进程不会被阻塞。

五、异步IO模型

这种模型的工做机制是告知内核我要启动某个操做,而且让内核在完成之后通知我,其中整个操做包含了数据从内核复制到用户进程中。

异步IO模型和信号驱动IO模型的区别在于,信号IO模型只是收到内核通知说数据准备完毕,可是复制数据这个操做仍是由用户进程来完成,可是异步IO模型从内核态复制数据到用户态包含通知用户进程都是在内核中进行完毕的。

 

 

咱们把几种常见的IO模型进行对比:

根据上述定义,前四种模型,阻塞IO,非阻塞IO,信号驱动IO,多路复用IO都是同步IO,只有最后一种才是真正的异步IO。

 

顺便贴一下关于IO多路复用的形象化理解:http://www.zhihu.com/question/32163005

 

参考资料:unix网络编程第六章部分章节

相关文章
相关标签/搜索