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

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. ABAP table control例子

    [转自]http://blog.csdn.net/lhx20/article/details/3039909Table control用于在screen上以表格的形式显示数据,在table contr ...

  2. ubunbu退出nano

    无意中进入ubuntu GNU nano ctrl+x即可退出

  3. UVALive - 7427 the math 【二分匹配】

    题目链接 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

  4. 装箱问题【STL】

    7-9 装箱问题(20 分) 假设有N项物品,大小分别为s​1​​.s​2​​.-.s​i​​.-.s​N​​,其中s​i​​为满足1≤s​i​​≤100的整数.要把这些物品装入到容量为100的一批箱 ...

  5. 【leetcode刷提笔记】Container With Most Water

    Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai).  ...

  6. SDUT 1048 Digital Roots

    Digital Roots Time Limit: 1000ms   Memory limit: 65536K 题目描述 The digital root of a positive integer ...

  7. EntityFramework 学习 一 Change Tracking in Entity Framework

    EntityFramework自动跟踪上下文中已经加载的实体,DbChangeTracker类给你关于当前实体的所有跟踪信息 注意,每个实体都要有EntityKey(主键)的属性,EntityFram ...

  8. Linux- AWS之EC2大数据集群定时开关机

    众所周知,云计算就是在计算你的钱,每当ec2开起来就要开始计费.当用户购买了一个庞大的与服务器做一个集群,尤其是用来做大数据集群,这些服务器的配置相当高,每台服务器所需要的费用不菲.其实在很多时候没能 ...

  9. matlab之sub2ind()函数

    将下标转换为线性索引 语法 linearInd = sub2ind(matrixSize, rowSub, colSub) 说明 linearInd = sub2ind(matrixSize, row ...

  10. ajax调试小技巧

    在编写ajax时出现了问题,通过myXmlHttpRequest.responseXML无法获取值. 可以尝试打印出responseText的值.截图如下所示: