IO模型:同步、异步、阻塞、非阻塞
前言:
在Linux的网络编程中,同步IO(synchronous IO)、异步IO(asynchronous IO)、阻塞IO(blocking IO)、非阻塞IO(non-blocking IO)究竟是什么?它们之间又有什么联系和区别? 本文是我对这个问题的答案整理的笔记,参考《UNIX网络编程.卷1》
一、IO模型
在《UNIX网络编程.卷1》第6.2节介绍了五种IO模型,分别是:
- 阻塞式IO(blocking IO)
- 非阻塞式IO(non-blocking IO)
- IO复用(IO multiplexing)
- 信号驱动式IO(signal driven IO)
- 异步IO(asynchronous IO)
通常一个 socket 上的读操作包含两个阶段:
- 等待数据准备好;
- 将数据从内核拷贝到进程中。
上述几种IO模型就是在这两个阶段上各有不同的情况。
1.1 阻塞式IO
默认情况下,Linux下的所有socket都是阻塞的。以 UDP 的recvfrom
调用为例:
当进程调用recvfrom
时,该函数直到①数据报到达且被复制到应用进程缓冲区;②或者发生错误(比如被信号中断)才返回。
所以,阻塞式IO的特点就是在I/O执行的两个阶段都被阻塞了——阻塞等待数据,阻塞拷贝数据。
1.2 非阻塞式IO
Linux下可以通过fcntl
将 socket 设置为非阻塞模式。
当对一个非阻塞 socket 执行读操作时,如果内核中的数据还没有准备好,那么它并不会阻塞用户进程,而是立刻返回一个EWOULDBLOCK
错误;如果内核中有数据准备好了,它会立即将数据拷贝到用户内存,并成功返回。
由于非阻塞I/O在没有数据时会立即返回,故用户进程通常需要循环调用recvfrom
,不断地主动询问内核数据是否ready。
所以,非阻塞式IO的特点是在I/O执行的第一个阶段不会阻塞线程,但在第二阶段会阻塞。
1.3 IO复用
IO复用(IO multiplexing),也称事件驱动IO(event-driven IO),就是在单个线程里同时监控多个套接字,通过 select 或 poll 轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程。
可以看出,进程阻塞在select
调用上,等待有套接字变为可读;当有套接字可读以后,调用recvfrom
把数据报从内核复制到用户进程缓冲区,此时进程阻塞在IO执行的第二个阶段。
如上图整个用户进程其实是一直被阻塞的,但IO复用的优势在于可以等待多个描述符就绪。
所以,IO复用的特点是进行了两次系统调用,进程先是阻塞在 select/poll 上,再是阻塞在读操作的第二个阶段上。
1.4 信号驱动式IO
信号驱动式IO(signal-driven IO),就是让内核在描述符就绪时发送SIGIO
信号通知用户进程。
首先需要开启 socket 的信号驱动式IO功能,然后通过sigaction
系统调用注册SIGIO信号处理函数 —— 该系统调用会立即返回。当数据准备好时,内核会为该进程产生一个SIGIO信号,这时就可以在信号处理函数中调用 recvfrom 读取数据了。
所以,信号驱动式IO的特点就是在等待数据ready期间进程不被阻塞,当收到信号通知时再阻塞并拷贝数据。
1.5 异步IO
异步IO(asynchronous IO)其实用得很少,在Linux 2.5 版本的内核中首次出现,在 2.6 版本的内核中才成为标准特性。
用户进程在发起aio_read
操作后,该系统调用立即返回 —— 然后内核会自己等待数据ready,并自动将数据拷贝到用户内存。整个过程完成以后,内核会给用户进程发送一个信号,通知IO操作已完成。
异步IO与信号驱动式IO的主要区别是:信号驱动式IO是由内核通知我们何时启动一个IO操作,而异步IO是由内核通知我们IO操作何时完成。
所以,异步IO的特点是IO执行的两个阶段都由内核去完成,用户进程无需干预,也不会被阻塞。
1.6 五种IO模型的比较
可以看出,前4种模型的主要区别在于第一阶段,因为它们的第二阶段是一样的:都是阻塞于recvfrom
调用,将数据从内核拷贝到用户进程缓冲区。
二、阻塞vs非阻塞,同步vs异步
回到本文开头的那个问题:同步IO、异步IO、阻塞IO、非阻塞IO究竟是什么?它们之间又有什么联系和区别?
阻塞IO vs 非阻塞IO
上面介绍阻塞式IO模型、非阻塞式IO模型时已经说明了两者的区别:
- 阻塞I/O会一直阻塞用户进程直到操作完成
- 非阻塞I/O在内核的数据还没准备好的情况下会立即返回
同步IO vs 异步IO
POSIX是这样定义的:
- A synchronous I/O operation causes the requesting process to be blocked until that I/O operation completes. —— 同步IO操作导致进程阻塞,直到IO操作完成。
- An asynchronous I/O operation does not cause the requesting process to be blocked. —— 异步IO操作不导致进程阻塞。
上面定义中的I/O operation
是指真正的I/O系统调用,比如recvfrom
,所以阻塞式I/O模型、非阻塞式I/O模型、I/O复用模型、信号驱动式I/O模型都属于同步I/O。—— 只有异步I/O模型属于POSIX定义的异步I/O,因为在异步I/O模型中,用户进程是将整个I/O操作都交给内核来完成,内核完成后发信号通知,在此期间用户进程完全不用去理会。
IO模型:同步、异步、阻塞、非阻塞的更多相关文章
- python并发编程之IO模型 同步 异步 阻塞 非阻塞
IO浅谈 首先 我们在谈及IO模型的时候,就必须要引入一个“操作系统”级别的调度者-系统内核(kernel),而阻塞非阻塞是跟进程/线程严密相关的,而进程/线程又是依赖于操作系统存在的,所以自然不能脱 ...
- IO模型《三》非阻塞IO
非阻塞IO(non-blocking IO) Linux下,可以通过设置socket使其变为non-blocking.当对一个non-blocking socket执行读操作时,流程是这个样子: 从图 ...
- 谈谈对不同I/O模型的理解 (阻塞/非阻塞IO,同步/异步IO)
一.关于I/O模型的问题 最近通过对ucore操作系统的学习,让我打开了操作系统内核这一黑盒子,与之前所学知识结合起来,解答了长久以来困扰我的关于I/O的一些问题. 1. 为什么redis能以单工作线 ...
- Python番外之 阻塞非阻塞,同步与异步,i/o模型
1. 概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式: 同步/异步主要针对C端: 同步: 所谓同步,就 ...
- linux基础编程:IO模型:阻塞/非阻塞/IO复用 同步/异步 Select/Epoll/AIO(转载)
IO概念 Linux的内核将所有外部设备都可以看做一个文件来操作.那么我们对与外部设备的操作都可以看做对文件进行操作.我们对一个文件的读写,都通过调用内核提供的系统调用:内核给我们返回一个file ...
- (转)同步异步,阻塞非阻塞 和nginx的IO模型
同步异步,阻塞非阻塞 和nginx的IO模型 原文:https://www.cnblogs.com/wxl-dede/p/5134636.html 同步与异步 同步和异步关注的是消息通信机制 (sy ...
- 转:IO模型-- 同步和阻塞,异步和非阻塞的区别
源地址 http://hi.baidu.com/deep_pro/item/db0c581af1c1f17e7b5f2534 这些词之间的区别难倒了很多人,还有什么同步阻塞, 同步非阻塞, 异步阻塞, ...
- 深入了解几种IO模型(阻塞非阻塞,同步异步)
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/zk3326312/article/details/79400805一般来说,Linux下系统IO主要 ...
- 哪5种IO模型?什么是select/poll/epoll?同步异步阻塞非阻塞有啥区别?全在这讲明白了!
系统中有哪5种IO模型?什么是 select/poll/epoll?同步异步阻塞非阻塞有啥区别? 本文地址http://yangjianyong.cn/?p=84转载无需经过作者本人授权 先解开第一个 ...
- IO模型同步与异步阻塞与非阻塞的区别
同步异步的区别 关注点:同步和异步关注的是消息通信机制 同步:所谓同步,就是在发出一个*调用*时,在没有得到结果之前,该*调用*就不返回.但是一旦调用返回,就得到返回值了.换句话说,就是由*调用者*主 ...
随机推荐
- (转)iOS 最佳实践
本文转自http://www.jianshu.com/p/b0bf2368fb95 感谢作者和译者 iOS最佳实践 iOS最佳实践 译者注 本文翻译自 futurice 公司的 iOS Good Pr ...
- Verilog学习笔记基本语法篇(三)·········赋值语句(待补充)
在Verilog HDL语言中,信号有两种赋值方式. A)非阻塞赋值(Non-Blocking)方式(如:b<=a;) (1)在语句块中,上面语句所赋值的变量不能立即为下面的语句所用: (2)块 ...
- cf 1016D
D. Vasya And The Matrix time limit per test 2 seconds memory limit per test 256 megabytes input stan ...
- PAT Basic 1048
1048 数字加密 本题要求实现一种数字加密方法.首先固定一个加密用正整数 A,对任一正整数 B,将其每 1 位数字与 A 的对应位置上的数字进行以下运算:对奇数位,对应位的数字相加后对 13 取余— ...
- js 获取json对象的Key、value
<script type="text/javascript"> getJson('age'); function getJson(key){ var jsonObj={ ...
- 八、docker的常用命令
1 Docker常用命令 1.1 存储镜像 如果要导出镜像到本地文件,可以使用 docker save 命令. docker save -o log_v140.tar docker.io/vmware ...
- iOS知识列表
Xib和StoryBoard,自动布局地图导航,实时公交,第三方地图应用本地推送通知,网络推送通知,真机调试,应用上传绘图,图表,曲线图 Xcode使用技巧多线程,runtime机制编码解码,加密设备 ...
- HDU——2955Robberies(小数背包)
Robberies Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- hibernate的cascade问题
cascade属性的可能值有 all: 所有情况下均进行关联操作,即save-update和delete. none: 所有情况下均不进行关联操作.这是默认值. save-update: 在执行sav ...
- LA 3644 简单并查集
题目大意:有一些简单的化合物,每个化合物由两种元素组成,把这些化合物按顺序装车,若k个化合物正好包含k种元素,那么就会爆炸.避免爆炸,有些化合物就不能装车.求有多少个不能装车. 题目分析:若k个化合物 ...