事件驱动模型:有个事件队列,把事件放到队列里,然后循环这个队列,取出事件执行

5种IO模式:

阻塞 I/O(blocking IO)

非阻塞 I/O(nonblocking IO)

I/O 多路复用(IO multiplexing)

信号驱动 I/O(signal driven IO)

异步 I/O(asynchronous IO)

其中信号驱动 I/O 并不常用

如果进行一次读取数据,数据会先被拷贝到操作系统内核的缓冲区中,然后会从操作系统内核的缓冲区拷贝到应用程序的地址空间

阻塞 I/O (blocking IO)

默认情况下所有的socket都是阻塞的,即一直等到有连接为止

阻塞 IO的特点就是在IO执行的阶段都被阻塞了

当用户要进行数据读取时,操作系统内核就开始准备数据,也就是说数据被拷贝到操作系统内核的缓冲区中的这个需要等待

而用户读取数据的进程也会被阻塞

当操作系统内核一直等到数据准备好了,它就会将数据从操作系统内核中拷贝到用户内存,这个也需要一定的时间,然后操作系统内核返回结果,用户进程才解除阻塞的状态,重新运行起来。

非阻塞 I/O (nonblocking IO)

非阻塞 IO的特点是用户进程不断地询问操作系统内核数据是否准备好

当用户要进行数据读取时,如果操作系统内核中的数据还没有准备好,它不会阻塞用户进程,而是立刻返回一个错误

用户进程发起一个读取数据操作后,并不需要等待,而是马上就得到了一个结果

用户进程判断结果是一个错误时,就知道操作系统内核中的数据还没有准备好,于是它再次发送读取数据操作

当操作系统内核中的数据准备好了,并且又收到了用户进程的询问,它就马上将数据拷贝到了用户内存,然后返回结果

I/O 多路复用(IO multiplexing)

IO 多路复用就是select,poll,epoll,这种IO模式就是事件驱动模型

select/epoll的好处就在于单个进程就可以同时处理多个网络连接的IO

select,poll,epoll方法会不断地轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程

当用户进程调用了select,整个进程就会被阻塞,而同时,操作系统内核会“监视”所有select负责的socket,当任何一个socket中的数据准备好了,select就会返回

这个时候用户进程再调用读取数据操作,将数据从操作系统内核拷贝到用户进程

异步 I/O(asynchronous IO)

用户进程发起读取数据操作之后,就可以去做其它的事

因为操作系统内核收到指令后,首先它会立刻返回,不会对用户进程产生任何阻塞,然后,操作系统内核会等待数据准备完成,然后将数据拷贝到用户内存,拷贝完成后,操作系统内核会给用户进程发送一个操作完成的结果

I/O 多路复用-select,poll,epoll

select

select支持多平台,select在单个进程中能够监视的文件描述符的数量存在限制,在Linux上一般为1024,可以通过修改宏定义甚至重新编译内核的方式提升这一限制

select()函数监视多个文件描述符的数组(writefds、readfds、exceptfds),调用后select()函数会阻塞,直到有描述符就绪(有数据 可读、可写、或者有错误),或者超时(timeout指定等待时间,如果立即返回设为null即可),函数返回。当select()函数返回后,该数组中就绪的文件描述符便会被内核修改标志位,使得进程可以获得这些文件描述符从而进行后续的读写操作

select()所维护的存储大量文件描述符的数据结构,随着文件描述符数量的增大,其复制的开销也线性增长。同时,由于网络响应时间的延迟使得大量TCP连接处于非活跃状态,但调用select()会对所有socket进行一次线性扫描,所以这也浪费了一定的开销

poll

poll和select在本质上没有多大差别,但是poll没有最大文件描述符数量的限制,select和poll都需要在返回后,通过遍历文件描述符来获取已经就绪的socket

poll和select同样存在一个缺点就是,包含大量文件描述符的数组被整体复制于用户态和内核的地址空间之间,而不论这些文件描述符是否就绪,它的开销随着文件描述符数量的增加而线性增大

select()和poll()将就绪的文件描述符告诉进程后,如果进程没有对其进行IO操作,那么下次调用select()或poll()的时候将再次报告这些文件描述符,所以它们一般不会丢失就绪的消息,这种方式称为水平触发(Level Triggered)

epoll

epoll可以同时支持水平触发和边缘触发(Edge Triggered,只告诉进程哪些文件描述符刚刚变为就绪状态,它只说一遍,如果我们没有采取行动,那么它将不会再次告知,这种方式称为边缘触发),理论上边缘触发的性能要更高一些,但是代码实现相当复杂。

当调用epoll_wait()获得就绪文件描述符时,返回的不是实际的描述符,而是一个代表就绪描述符数量的值,只需要去epoll指定的一个数组中依次取得相应数量的文件描述符即可,这里也使用了内存映射(mmap)技术,这样便彻底省掉了这些文件描述符在系统调用时复制的开销。

epoll事先通过epoll_ctl()来注册一个文件描述符,一旦基于某个文件描述符就绪时,内核会采用类似callback的回调机制,迅速激活这个文件描述符,当进程调用epoll_wait()时便得到通知

参考:https://segmentfault.com/a/1190000003063859

Python-IO模式介绍的更多相关文章

  1. python IO模式(多路复用和异步IO深入理解)

    1.事件渠道模型.事件渠道为异步IO的原型. 2.IO模式,一次IO调用会经历两个阶段.一.等待数据阶段,将数据从网络或者是磁盘读取到系统内核(kennel) 二.将数据从内核拷贝到进程中. 基于这两 ...

  2. Python IO 模式

    IO 模式 对于 Linux 的 network IO: 一次 IO 访问(以read举例),数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区 copy 到应用程序的地址空间.所 ...

  3. python 全栈开发,Day44(IO模型介绍,阻塞IO,非阻塞IO,多路复用IO,异步IO,IO模型比较分析,selectors模块,垃圾回收机制)

    昨日内容回顾 协程实际上是一个线程,执行了多个任务,遇到IO就切换 切换,可以使用yield,greenlet 遇到IO gevent: 检测到IO,能够使用greenlet实现自动切换,规避了IO阻 ...

  4. {python之IO多路复用} IO模型介绍 阻塞IO(blocking IO) 非阻塞IO(non-blocking IO) 多路复用IO(IO multiplexing) 异步IO(Asynchronous I/O) IO模型比较分析 selectors模块

    python之IO多路复用 阅读目录 一 IO模型介绍 二 阻塞IO(blocking IO) 三 非阻塞IO(non-blocking IO) 四 多路复用IO(IO multiplexing) 五 ...

  5. python全栈开发,Day44(IO模型介绍,阻塞IO,非阻塞IO,多路复用IO,异步IO,IO模型比较分析,selectors模块,垃圾回收机制)

    昨日内容回顾 协程实际上是一个线程,执行了多个任务,遇到IO就切换 切换,可以使用yield,greenlet 遇到IO gevent: 检测到IO,能够使用greenlet实现自动切换,规避了IO阻 ...

  6. python使用rabbitMQ介绍五(话题模式)

    一.模式介绍 话题模式(Topic)基本思想和路由模式是一样的,只不过路由键支持模糊匹配,符号“#”匹配一个或多个词,符号“*”匹配不多不少一个词 话题模式相当于消息的模糊匹配,或者按照正则匹配.其中 ...

  7. python使用rabbitMQ介绍三(发布订阅模式)

    一.模式介绍 在前面的例子中,消息直接发送到queue中. 现在介绍的模式,消息发送到exchange中,消费者把队列绑定到exchange上. 发布-订阅模式是把消息广播到每个消费者,每个消费者接收 ...

  8. python使用rabbitMQ介绍二(工作队列模式)

    一模式介绍 第一章节的生产-消费者模式,是非常简单的模式,一发一收.在实际的应用中,消费者有的时候需要工作较长的时间,则需要增加消费者. 队列模型: 这时mq实现了一下几个功能: rabbitmq循环 ...

  9. python使用rabbitMQ介绍一(生产-消费者模式)

    1 模式介绍 生产者-消费者模式是最简单的使用模式. 一个生产者P,给队列发送消息,一个消费者C来取队列的消息. 这里的队列长度不限,生产者和消费者都不用考虑队列的长度. 队列的模型图: 2 示例代码 ...

  10. IO模式调查利器blkiomon介绍

    本文链接地址: IO模式调查利器blkiomon介绍 blkiomon 是blktrace工具包带的一个方便用户了解IO情况的工具, 由于blktrace太专业,需要了解的IO协议栈的东西太多,blk ...

随机推荐

  1. android 中使用svg

    http://www.see-source.com/blog/300000038/1189.html http://www.jianshu.com/p/30dfa5920658#

  2. python基础16 ----面向对象程序设计二

    一.继承与派生 1.继承的定义:继承是一种创建新类的方式,即在类中提取共同的部分创建出一个类,这样的类称为父类,也可称为基类和超类,新建的类称为派生类或子类. 2.单继承:就相当于子类继承了一个父类. ...

  3. php自定义的格式化时间示例代码

    时间刚好是5分钟前,则对应的时间戳就会被格式化为5分钟前,自定义的格式化时间方法如下,感兴趣的朋友可以参考下 如:时间刚好是5分钟前,则对应的时间戳就会被格式化为5分钟前,不多说了,直接贴上代码: 复 ...

  4. CSS3滑块菜单

    在线演示 本地下载

  5. 第七篇、os、sys、random、time、datetime、logging

    一.sys 用于提供对Python解释器相关的操作: 1 2 3 4 5 6 7 8 9 sys.argv           命令行参数List,第一个元素是程序本身路径 sys.exit(n)   ...

  6. castle windsor学习-----XML Inline Parameters 内联参数

    当使用XML配置的时候,可能要给组件指定各种各样的依赖 1.简单的参数 参数名称不区分大小写 <component id="ping" type="Acme.Crm ...

  7. 大话设计模式--解释器模式 interpreter -- C++实现实例

    1. 解释器模式: 给定一个语言,定义它的文法的一种表示 并 定义一个解释器,这个解释器使用该表示文法 来解释语言中的句子. 如果一种特定类型的问题发生的频率很高,那么可能就值得将该问题的各个实例表述 ...

  8. UOJ136 开学前的作文

    描述 红包是一个萌萌的男孩子. 红包由于 NOI 惨挂,直到前不久依然无心写作业.如今快开学了,他决定好好完成作业. 对于可以交电子稿的作文,红包有特殊的完成技巧,大致流程是依次选中一段内容→按下 C ...

  9. C++的栈

    栈,是一种存储受限的线性数据结构,在存储和访问数据的时候只能访问栈的一端.栈类似于一摞盘子,只能拿去最上面的盘子,也只能把盘子放到最上面.由于这种特点,栈是一种后进先出(Last in / First ...

  10. JS命令模式个人理解

    JS命令模式个人理解 //BODY部分<body> <button id="execute">打开电视</button> <button ...