参考《unix网络编程》

参考http://blog.csdn.net/blueboy2000/article/details/4485874

参考http://blog.csdn.net/suxinpingtao51/article/details/46314097

五种I/O模型

  1. 阻塞I/O:应用程序调用一个IO函数,导致应用程序阻塞,如果数据已经准备好,从内核拷贝到用户空间,否则一直等待下去

  2. 非阻塞I/O:

  3. I/O复用(select和poll)

  4. 信号驱动I/O(SIGIO)

  5. 异步I/O(Posix.1的aio_系列函数)

一个输入操作通常包括两个阶段:
1.等待数据准备好
2.从内核向进程复制数据
对于一个套接字上的输入操作,第一步通常涉及等待数据从网络中到达,当所有等待分组到达时,它被复制到内核中的某个缓冲区。第二步就是将数据从内核缓冲区复制到应用进程的缓冲区
阻塞I/O:应用程序调用一个IO函数,导致应用程序阻塞,如果数据已经准备好,从内核拷贝到用户空间,否则一直等待下去
非阻塞I/O模型 
我们把一个套接口设置为非阻塞就是告诉内核,当所请求的I/O操作无法完成时,不要将进程睡眠,而是返回一个错误。这样我们的I/O操作函数将不断的测试数据是否已经准备好,如果没有准备好,继续测试,直到数据准备好为止。在这个不断测试的过程中,会大量的占用CPU的时间
当一个应用程序像这样对一个非阻塞描述符循环调用recvfrom时,我们称之为轮循(polling)
总结:阻塞I/O模式下,虽然不会占用大量的CPU时间,一个线程只能处理一个流的I/O事件。如果想要同时处理多个流,要么多进程(fork),要么多线程(pthread_create),很不幸这两种方法效率都不高。于是再来考虑非阻塞忙轮询的I/O方式,我们发现我们可以同时处理多个流了(把一个流从阻塞模式切换到非阻塞模式再此不予讨论):
[cpp] view plain copy
  1. <span style="font-family:Microsoft YaHei;font-size:14px;">while true {
  2. for i in stream[]; {
  3. if i has data
  4. read until unavailable
  5. }
  6. }</span>
    我们只要不停的把所有流从头到尾问一遍,又从头开始。这样就可以处理多个流了,但这样的做法显然不好,因为如果所有的流都没有数据,那么只会白白浪费CPU。
为了避免CPU空转,可以引进了一个代理(一开始有一位叫做select的代理,后来又有一位叫做poll的代理,不过两者的本质是一样的)。这个代理比较厉害,可以同时观察许多流的I/O事件,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有I/O事件时,就从阻塞态中醒来,于是我们的程序就会轮询一遍所有的流(于是我们可以把“忙”字去掉了)
[cpp] view plain copy
  1. <span style="font-family:Microsoft YaHei;font-size:14px;">while true {
  2. select(streams[])
  3. for i in streams[] {
  4. if i has data
  5. read until unavailable
  6. }
  7. }</span>
于是,如果没有I/O事件产生,我们的程序就会阻塞在select处。但是依然有个问题,我们从select那里仅仅知道了,有I/O事件发生了,但却并不知道是那几个流(可能有一个,多个,甚至全部),我们只能无差别轮询所有流,找出能读出数据,或者写入数据的流,对他们进行操作。即使用select,我们有O(n)的无差别轮询复杂度,同时处理的流越多,没一次无差别轮询时间就越长。
epoll可以理解为event poll,不同于忙轮询和无差别轮询,epoll之会把哪个流发生了怎样的I/O事件通知我们。此时我们对这些流的操作都是有意义的。(复杂度降低到了O(1))

I/O复用模型 
I/O复用模型会用到select或者poll函数,这两个函数也会使进程阻塞,但是和阻塞I/O所不同的的,这两个函数可以同时阻塞多个I/O操作。而且可以同时对多个读操作,多个写操作的I/O函数进行检测,直到有数据可读或可写时,才真正调用I/O操作函数。 
我们阻塞于select调用,等待数据报套接字变为可读。当select返回套接字可读这一条件时,我们调用recefrom把所有读数据报复制到应用进程缓冲区。
信号驱动I/O模型 
我们也可以用信号,让内核在描述符就绪时发送SIGIO信号通知我们。通过sigaction系统调用安装一个信号处理函数。该系统调用将立即返回,我们的进程继续工作,也就是说它没有被阻塞。当数据报准备好读取时,内核就为该进程产生一个SIGIO信号。我们随后既可以在信号处理函数中调用recvfrom读取数据报,并通知主循环数据已经准备好待处理。
优势:等待数据报到达期间进程不被阻塞。主循环可以继续执行,只要等待来自信号处理函数的通知:既可以是数据已准备好被处理,也可以是数据报已准备好被读取。
异步I/O模型 
告知内核启动某个操作,并让内核在整个操作(包括将内核复制到我们自己的缓冲区)完成后通知我们。
与信号驱动模型的主要区别在于:信号驱动式I/O是由内核通知我们何时可以启动一个I/O操作,而异步模型是由内核通知我们I/O操作何时完成。

调用aio_read函数,告诉内核描述字,缓冲区指针,缓冲区大小,文件偏移以及通知的方式,然后立即返回。当内核将数据拷贝到缓冲区后,再通知应用程序。

各种I/O模型的对比:

同步I/O和异步I/O对比:同步I/O操作导致请求阻塞(前4种模型是是同步I/O模型),直到I/O操作完成;异步I/O操作不导致请求进程阻塞。

http://www.cnblogs.com/Anker/p/3265058.html

select, poll, epoll区别以及原理

介绍epoll中函数,以及它们的使用, ET和LT是区别

IO模型(select, poll, epoll的区别和原理)相关推荐

  1. IO多路复用select,poll epoll以及区别

    看这个一次读懂 Select.Poll.Epoll IO复用技术 文章来简单理解下,如果不是很明白的话,可以参考下面转的知乎上面白话文列子 作者:Leslie 链接:https://www.zhihu ...

  2. IO多路复用select/poll/epoll详解以及在Python中的应用

    IO multiplexing(IO多路复用) IO多路复用,有些地方称之为event driven IO(事件驱动IO). 它的好处在于单个进程可以处理多个网络IO请求.select/epoll这两 ...

  3. python3 异步 非阻塞 IO多路复用 select poll epoll 使用

    有许多封装好的异步非阻塞IO多路复用框架,底层在linux基于最新的epoll实现,为了更好的使用,了解其底层原理还是有必要的. 下面记录下分别基于Select/Poll/Epoll的echo ser ...

  4. Python异步非阻塞IO多路复用Select/Poll/Epoll使用

    来源:http://www.haiyun.me/archives/1056.html 有许多封装好的异步非阻塞IO多路复用框架,底层在linux基于最新的epoll实现,为了更好的使用,了解其底层原理 ...

  5. python poll_python IO 多路复用 select poll epoll

    select select 原理 select 是通过系统调用来监视着一个由多个文件描述符(file descriptor)组成的数组,当select()返回后,数组中就绪的文件描述符会被内核修改标记 ...

  6. Python之路-python(Queue队列、进程、Gevent协程、Select\Poll\Epoll异步IO与事件驱动)

    一.进程: 1.语法 2.进程间通讯 3.进程池 二.Gevent协程 三.Select\Poll\Epoll异步IO与事件驱动 一.进程: 1.语法 1 简单的启动线程语法 2 def run(na ...

  7. select poll epoll IO操作多路复用及猴子补丁

    一:select(能监控数量有限,不能告诉用户程序具体那个连接有数据) select目前几乎所有的平台都支持,其良好的跨平台支持也是一个优点 select的缺点在于单个进程能够监控的文件描述的数量存在 ...

  8. C++面试 select poll epoll之间的区别

    目录 摘要 场景描述 Select poll epoll 总结 摘要 先明确几个概念: 面试官问:给我讲讲什么事同步阻塞.异步阻塞.同步非阻塞.异步非阻塞. 我:????? 同步和异步的概念 同步是指 ...

  9. select,poll,epoll区别面试常问

    select,poll,epoll区别: select优点 1)select()的可移植性更好,在某些Unix系统上不支持poll() 2)select() 对于超时值提供了更好的精度:微秒,而pol ...

最新文章

  1. sharepoint2013用户切换实现方式
  2. QML范围和命名分辨率
  3. 如何给网页标题添加icon小图标
  4. tps是什么意思_系统了解精益生产系统TPS精益思想丛书介绍
  5. 填表法解“银行家算法”问题
  6. Ubuntu屏幕录制工具【转】
  7. 最保值电子产品绝对是它:后悔没多收几台
  8. pycharm中安装三方库和cmd下载三方库的选择与区别
  9. MATLAB程序设计的绘图函数
  10. vscode 路径宏_VSCode宏怎么设置?VSCode宏的添加方法!
  11. 调用谷歌Chrome浏览器打不开网页崩溃了
  12. video-react
  13. 浙大计算机学硕453分,卷卷卷!2021计算机专业考研神仙打架:浙大最高分超450,人均400+?...
  14. php sphinx应用场景,Sphinx+Scws 搭建千万级准实时搜索应用场景详解
  15. 基于webrtc技术的远程桌面控制系统(一)
  16. 数学建模培训笔记记录--8.3
  17. 能加密的写日记小工具(解压可用,无需安装)
  18. 计算机桌面收纳盒进么建立,桌面收纳盒制作图解教程
  19. 复合类型与with关键字
  20. Pyspider框架工作流程及常见问题

热门文章

  1. 图片转圈实现_如何编辑图片?
  2. JAVA数组扁平化整合_数组扁平化的几种处理放法
  3. linux tomcat 清空war,Linux下tomcat部署war包
  4. php多图片上传并回显,如何用input标签和jquery实现多图片的上传和回显功能
  5. bLue的二叉树_JAVA
  6. c++ 从混合中英文数字等的string 中按顺序分别输出
  7. 7、Linux中文件类型、文件属性
  8. 使用 Binlog 和 Canal 从 MySQL 抽取数据
  9. jvm系列(七):jvm调优-工具篇
  10. Java 基本数据类型