阻塞(blocking)、非阻塞(non-blocking):最常听到阻塞与非阻塞这两个词就是在函数调用中,比如waitid这个函数,通过NOHANG参数可以把waitid设置为非阻塞的,也就是问询一遍子进程,看看有没有可回收子进程,如果没有,直接返回不等待,而如果不设置NOHANG,waitid会一直问询子进程,直到有一个可回收子进程再返回,也就是说如果没有子进程可回收,waitid会一直阻塞在这条函数调用上,后面的操作就无法执行。如果把函数调用笼统的规划到一个事件的执行,那么阻塞与非阻塞的区别就是 是否仅仅只等待事件完成(事件返回)才进行下一步操作。比如 烧开水这个例子(参考资料中有提到),如果人从水壶开始烧水到水烧开这段时间一直在水壶前等待烧水,这就是阻塞,如果人比较聪明,在水壶烧水的过程中,人去看电视了或者干其他事情了,这就是不阻塞的,但是在这种情况下,人想要知道水是否烧开了,只能隔一段时间去看一下水壶“烧开了没有?”,这个隔一段时间去看一下的方法 就是 轮询。所以,再回到waitid这个例子,我们设置NOHANG参数的时候,一般都要在waitid上加一个用于轮询的循环。

同步(synchronous)、异步(asynchronous):同步和异步,一开始看很容易把同步和阻塞的概念混淆在一起,我倾向于将同步理解为一种现象,而阻塞/非阻塞作为这个现象中的某种状态存在。同步和异步的区别,参考资料中的说法我觉得虽然把同步异步区别说出来了,但是同步和阻塞还是很容易混淆。那我再对烧开水这个例子重写一下以供参考,水壶分为 普通水壶 和 智能水壶,普通水壶需要人手工操作,需要人判断水是否烧开,水烧开了需要人把水壶从火上拿下来(不然会溢出来),而智能水壶提供两个作用,水烧开后自动关火并且发出响声提示人水已经烧好。烧开水就分为了两个过程,等待水开和拿开水壶,首先说同步和异步,同步就是使用普通水壶烧水,水烧开后需要人主动拿开水壶,而等待水烧开的这个过程可以是阻塞(站那等)的和非阻塞(看电视轮询)的,整个操作需要人的全程参与;异步就是使用智能水壶烧水,等待水开的过程人可以干任何事(即异步本身就是非阻塞的,所以异步并不区分阻塞/非阻塞)并且人不用关心水是否烧开(敲重点),水烧开后,智能水壶会发出响声提示人(发出信号),这完成了等待水开这第一过程,紧接着,智能水壶会自动关火,这代替了人拿开水壶的这个动作完成了第二过程。可以发现,同步整个过程需要人全程参与,而异步整个过程是两个“人”在做,一个“人”就是这个智能水壶,一个人就是始终在做其他事的人,这个人将烧开水这件事托管给了智能水壶由智能水壶完成一切过程,最后提示人完成了。因此,判断同步只需要看,事件的监管和完成方是不是事件发起者即可。

在接下来即将要说到的IO操作中,异步IO就是进程将IO操作完全交由内核控制,由内核中的DMA控制器完成全部IO操作并在完成后通过信号提示进程IO操作已完成,这也是两个“人”的事情,进程将IO托管给DMA控制器,而进程又可以干其他的事,二者在不同的事件上各自执行操作,是并行的。

IO模式:

比如对于一个read操作发生时,它会经历下面两个阶段:

A, 等待数据准备,数据是否拷贝到内核缓冲区;

B, 将数据从内核拷贝到用户进程空间

如果把这两个阶段对应到前文中我写的烧开水的两个过程中,对于下面的几种IO模式就容易理解的多。

《Unix网络编程卷1:套接字联网API》(即UNP)中第六章对unix 系统将IO模型分为五类:阻塞IO,非阻塞IO,IO复用,信号驱动,异步IO

1、阻塞IO:A阶段阻塞等待,进程调用recvfrom询问内核数据是否准备好,直到数据准备好再返回。(注意:由内核监听数据,进程询问内核数据是否准备好)

2、非阻塞IO:A阶段非阻塞等待,即采用轮询机制(即进程不断的询问内核数据是否准备好(不断调用recvfrom),这么做往往消耗大量CPU时间)判断数据是否拷贝到内核缓冲区。

3、IO复用:IO复用技术是对阻塞IO的改进,首先非阻塞大量消耗CPU,不予考虑。在数据准备阶段,内核监听一个IO也好,监听一群IO也好,都在监听,因此复用,就是内核同时监听进程的多个IO操作,在进程询问时返回有数据到来的IO。此时进程不是阻塞在recvfrom上,而是阻塞在IO复用系统调用——select、poll、epoll上,这几个系统调用会在所监听的所有IO中某个或某几个有数据到来时返回。

多路IO共用一个同步阻塞接口,任意IO可操作都可激活IO操作,这是对阻塞IO的改进(主要是select和poll、epoll,关键是能实现同时对多个IO端口进行监听)。此时阻塞发生在select/poll的系统调用上,而不是阻塞在实际的I/O系统调用上。IO多路复用的高级之处在于:它能同时等待多个文件描述符,而这些文件描述符(套接字描述符)其中的任意一个进入读就绪状态,select等函数就可以返回。

4、信号驱动

注册一个IO信号事件,在数据可操作时通过SIGIO信号通知线程,这应该算是一种异步机制;

5、异步IO:进程通知内核完成一个IO操作,由内核完成A+B阶段后通知进程。

参考中的这张图很好的解释了上述5种IO模型。

POSIX将IO只分成了同步IO、异步IO两种模型。

同步I/O操作:实际的I/O操作将导致请求进程阻塞,直到I/O操作完成。

异步I/O操作:实际的I/O操作不导致请求进程阻塞。

由此,阻塞式I/O,非阻塞式I/O,I/O复用,信号驱动I/O模型都属于同步I/O,因为第二阶段的数据复制都是阻塞的,也可以理解为都由进程完成。而只有异步I/O模型属于这里的异步I/O操作(IO由内核完成)。

参考资料:知乎Linux分享官

bilibili视频

《Unix网络编程卷1:套接字联网API(第3版)》6.2 IO模型

IO模式 select、poll、epoll的更多相关文章

  1. 转一贴,今天实在写累了,也看累了--【Python异步非阻塞IO多路复用Select/Poll/Epoll使用】

    下面这篇,原理理解了, 再结合 这一周来的心得体会,整个框架就差不多了... http://www.haiyun.me/archives/1056.html 有许多封装好的异步非阻塞IO多路复用框架, ...

  2. Python异步非阻塞IO多路复用Select/Poll/Epoll使用,线程,进程,协程

    1.使用select模拟socketserver伪并发处理客户端请求,代码如下: import socket import select sk = socket.socket() sk.bind((' ...

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

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

  4. 最快理解 - IO多路复用:select / poll / epoll 的区别.

    目录 第一个解决方案(多线程) 第二个解决方案(select) 第三个解决方案(poll) 最终解决方案(epoll) 客栈遇到的问题 从开始学习编程后,我就想开一个 Hello World 餐厅,由 ...

  5. python的协程和异步io【select|poll|epoll】

    协程又叫做微线程,协程是一种用户态的轻量级的线程,操作系统根本就不知道协程的存在,完全由用户来控制,协程拥有自己的的寄存器的上下文和栈,协程调度切换时,将寄存器上下文和栈保存到其他地方,在切换回来后, ...

  6. Linux IO多路复用 select/poll/epoll

    Select -- synchronius I/O multiplexing select, FS_SET,FD_CLR,FD_ISSET,FD_ZERO #include <sys/time. ...

  7. python网络编程——IO多路复用select/poll/epoll的使用

    转载博客: http://www.haiyun.me/archives/1056.html http://www.cnblogs.com/coser/archive/2012/01/06/231521 ...

  8. Linux IO模式以及select poll epoll详解

    一 背景 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案是不同的.所以先限定一下本文的上下文. 本文讨论的背景是Linux环境下的network ...

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

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

  10. Python自动化 【第十篇】:Python进阶-多进程/协程/事件驱动与Select\Poll\Epoll异步IO

    本节内容: 多进程 协程 事件驱动与Select\Poll\Epoll异步IO   1.  多进程 启动多个进程 进程中启进程 父进程与子进程 进程间通信 不同进程间内存是不共享的,要想实现两个进程间 ...

随机推荐

  1. 批量安装Zabbix_Agent

    使用自动化部署工具Ansible批量部署zabbix_agent. 1. 安装Ansible yum –y install ansible 内网情况下,现在ansible及其依赖的rpm包,添加到yu ...

  2. 专题三:redis的数据类型之hash

    一.基本介绍 前面一个专题我们讲到string去存储明星微博粉丝数,微博数等,大概介绍了两种方式: set user:id:012345:fans  12210862            set u ...

  3. WC2019 自闭记

    不咕了 Day 1 2019/1/24 辣么快就到冬令营了,还沉迷于被柿子吊打的状态的菜鸡一时半会还反应不过来.我们学校这次分头去的冬令营,差点上不了车.这次做的动车居然直达广州,强啊. 然鹅还是到太 ...

  4. [Luogu P2051] [AHOI2009]中国象棋 (状压DP->网格DP)

    题面 传送门:https://www.luogu.org/problemnew/show/P2051 Solution 看到这题,我们不妨先看一下数据范围 30pt:n,m<=6 显然搜索,直接 ...

  5. Python列表lists索引关于字符串小纪

    看的出'字符串列表'中的空格也是计算在内的

  6. Polyglot Translators: Let's do i18n easier! 一款国际化插件小助手!

    在做国际化文本有关的工作时, 是否厌倦了在不同应用或者网页之间频繁地切换进行中文, 繁体, 英文甚至韩文日文的文本翻译工作? 好吧, 我就是受不了频繁在进行文本字符串的转换, 还得跑到百度翻译上面搜索 ...

  7. python开发初识(一)

    python开发 机器码和字节码 机器码 :计算机可以直接认识的语言 字节码 :高级语言转换成机器码去执行 语言之间的对比: C,汇编 :C语言是根语言 python Java :既能写前端,又能写后 ...

  8. bash中选择结构、循环结构与break、continue

    if两种选择结构 if 测试条件; then 程序块 else 程序块 fi if 测试条件1; then 程序块 elif 测试条件2; then 程序块 ... elif 程序条件n; then ...

  9. 1.使用javax.mail, spring的JavaMailSender,springboot发送邮件

    一.java发邮件 电子邮件服务器:这些邮件服务器就类似于邮局,它主要负责接收用户投递过来的邮件,并把邮件投递到邮件接收者的电子邮箱中,按功能划分有两种类型 SMTP邮件服务器:用户替用户发送邮件和接 ...

  10. fidder 学习

    前提 你要清楚下面两个问题的答案 1.接口是什么? 2.抓包是什么? 在提一嘴 想要获取手机上的时时请求 首先要把手机和电脑连接同一个网络 也就是在同一频道上 开始 1.安装 Fidder Every ...