阻塞(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. puk2367 拓扑排序

    Description The system of Martians' blood relations is confusing enough. Actually, Martians bud when ...

  2. 简单的学生管理(C语言)

    #include<stdio.h> #include<stdlib.h> #include<string.h> struct Student_type{ char ...

  3. CodeForces 1426F Number of Subsequences

    题意 给定一个长度为 \(n\) 的串,只包含 abc 和通配符.通配符可以替换 abc 的一个.求所有得到的字符串中子序列 abc 出现的次数,对 \(10^9+7\) 取模. \(\texttt{ ...

  4. 这篇文章揭开python进程、线程、协程神秘的面纱

    1.概念 [关注公众号"轻松学编程"了解更多. 回复"协程"获取本文源代码.] 从计算机硬件角度: 计算机的核心是CPU,承担了所有的计算任务. 一个CPU,在 ...

  5. Java_进程与线程

    进Process&Thread 区别 进程 线程 根本区别 作为资源分配的单位 调度和执行的单位 开销 每个进程都有独立的代码和数据空间(进程上下文), 进程间的切换会有较大的开销 线程可以看 ...

  6. 利用ms08_067入侵window xp sp1(English)版本

    前几天上课,老师搬出实验,自己体验了一下 1.环境配置 需要准备kali(攻击机),window xp (我这里是sp1 英文版本,标题很清楚了),攻击机和目标靶机要在同意网段下我的kali(192. ...

  7. python编写实现抽奖器

    这篇文章主要为大家详细介绍了python编写实现抽奖器,文中代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 # coding=utf-8 import sys import os ...

  8. nginx&http 第三章 惊群

    惊群:概念就不解释了. 直接说正题:惊群问题一般出现在那些web服务器上,Linux系统有个经典的accept惊群问题,这个问题现在已经在内核曾经得以解决,具体来讲就是当有新的连接进入到accept队 ...

  9. 《GNU_makefile》第七章——makefile的条件执行

    条件执行即,通过变量的值,来控制make的执行和忽略. 条件执行只能控制makefile的make语法部分,不能控制shell部分 1.一个例子 - libs_for_gcc = -lgnu norm ...

  10. mysql中delete from t1 where id = 10加锁状况叙述

    在Next_Key Lock算法中,不仅仅锁定住所找到的索引,而且还锁定住这些索引覆盖的范围.因此在这个范围内的插入都是不允许的.这样就避免了在这个范围内插入数据导致的幻读问题. delete fro ...