Linux下5种IO模型的小结
接触网络编程,我们时常会与各种与IO相关的概念打交道:同步(Synchronous)、异步(ASynchronous)、阻塞(blocking)和非阻塞(non-blocking)。关于概念的区别在知乎上看到一位朋友(链接)打了一个比较形象的比喻:
你打电话问书店老板有没有《分布式系统》这本书,如果是同步通信机制,书店老板会说,你稍等,”我查一下",然后开始查啊查,等查好了(可能是5秒,也可能是一天)告诉你结果(返回结果)。
而异步通信机制,书店老板直接告诉你我查一下啊,查好了打电话给你,然后直接挂电话了(不返回结果)。然后查好了,他会主动打电话给你。在这里老板通过“回电”这种方式来回调。你打电话问书店老板有没有《分布式系统》这本书,你如果是阻塞式调用,你会一直把自己“挂起”,直到得到这本书有没有的结果。如果是非阻塞式调用,你不管老板有没有告诉你,你自己先一边去玩了, 当然你也要偶尔过几分钟check一下老板有没有返回结果。
在这里阻塞与非阻塞与是否同步异步无关。跟老板通过什么方式回答你结果无关。
同步与异步的主要区别就在于:会不会导致请求进程(或线程)阻塞。同步会使请求进程(或线程)阻塞而异步不会。
linux下有五种常见的IO模型,其中只有一种异步模型,其余皆为同步模型。如图:

阻塞IO模型是最常见的IO模型了,对于所有的“慢速设备”(socket、pipe、fifo、terminal)的IO默认的方式都是阻塞的方式。阻塞就是进程放弃cpu,让给其他进程使用cpu。进程阻塞最显著的表现就是“进程睡眠了”。阻塞的时间通常取决于“数据”是否到来。

非阻塞IO就是设置IO相关的系统调用为non-blocaking,随后进行的IO操作无论有没有可用数据都会立即返回,并设置errno为EWOULDBLOCK或者EAGAIN。我们可以通过主动check的方式(polling,轮询)确保IO有效时,随之进行相关的IO操作。当然这种方式看起来就似乎不太靠谱,浪费了太多的CPU时间,用宝贵的CPU时间做轮询太不靠谱儿了。图示:

多路复用是让阻塞发生在我们的多路复用IO操作的系统调用上面,而不是我们真正去执行IO的系统调用。使用这个方式的好处就是可以同时监控多个用于IO的文件描述符。详细的使用方式之前写了一篇博客有提到:http://www.cnblogs.com/ittinybird/p/4574397.html

所谓信号驱动,就是利用信号机制,安装信号SIGIO的处理函数(进行IO相关操作),通过监控文件描述符,当其就绪时,通知目标进程进行IO操作(signal handler)。具体使用方法之前博客也有说明:http://www.cnblogs.com/ittinybird/p/4574397.html

Linux上异步IO有一组POSIX规定的接口,已aio开头的几个SYSCALL。如下:
int aio_read(struct aiocb *aiocbp);
int aio_write(struct aiocb *aiocbp);
ssize_t aio_return(struct aiocb *aiocbp);
使用时记得 Link with -lrt.
参数看起来给人一种很简洁的假象。其实相较于其他模型的参数一个也没有少,只是放到了结构体里边了。先看一下struct aiocb这个结构的原型吧,头文件是”aio.h“。
struct aiocb
{
int aio_fildes; /* File desriptor. */
int aio_lio_opcode; /* Operation to be performed. */
int aio_reqprio; /* Request priority offset. */
volatile void *aio_buf; /* Location of buffer. */
size_t aio_nbytes; /* Length of transfer. */
struct sigevent aio_sigevent; /* Signal number and value. */ /* Internal members. */
struct aiocb *__next_prio;
int __abs_prio;
int __policy;
int __error_code;
__ssize_t __return_value; #ifndef __USE_FILE_OFFSET64
__off_t aio_offset; /* File offset. */
char __pad[sizeof (__off64_t) - sizeof (__off_t)];
#else
__off64_t aio_offset; /* File offset. */
#endif
char __unused[];
};
其实虽然结构体足够长,其实真正用到的也就前面那几个参数,也没那么复杂。具体用法不再赘述。具体可以参考以为网友的博文:http://blog.csdn.net/tq02h2a/article/details/3825114。
下图是关于异步IO模型的图示:

aio(7) - Linux manual page http://man7.org/linux/man-pages/man7/aio.7.html
sigevent(7) - Linux manual page http://man7.org/linux/man-pages/man7/sigevent.7.html
5张模型图片出处 《UNIX网络编程卷1》 史蒂文斯
Linux下5种IO模型的小结的更多相关文章
- Linux的五种IO模型及同步和异步的区别
前置知识 缓存 I/O 缓存 I/O 又被称作标准 I/O,大多数文件系统的默认 I/O 操作都是缓存 I/O.在 Linux 的缓存 I/O 机制中,操作系统会将 I/O 的数据缓存在文件系统的页缓 ...
- linux的五种IO模型
概念: 同步.异步.阻塞.非阻塞的概念 同步:所谓同步,发起一个功能调用的时候,在没有得到结果之前,该调用不返回,也就是必须一件事一件事的做,等前一件做完了,才能做下一件. 提交请求->等待服务 ...
- 浅聊Linux的五种IO模型
在日常 Coding 中,多多少少都会接触到网络 IO,就会想要深入了解一下.看了很多文章,总是云里雾里的感觉,直到读了<UNIX网络编程 卷1:套接字联网API>中的介绍后,才豁然开朗. ...
- Linux下常见的IO模型
前言 阻塞IO(blocking IO) 非阻塞IO(nonblocking IO) IO复用(IO multiplexing) 异步IO(asynchronous IO (the POSIX aio ...
- 从操作系统层面理解Linux下的网络IO模型
I/O( INPUT OUTPUT),包括文件I/O.网络I/O. 计算机世界里的速度鄙视: 内存读数据:纳秒级别. 千兆网卡读数据:微妙级别.1微秒=1000纳秒,网卡比内存慢了千倍. 磁盘读数据: ...
- Unix下五种IO模型
http://blog.chinaunix.net/uid-25324849-id-247813.html 1. I/O模型 Unix下共有五种I/O模型 a. 阻塞I/O b. 非阻塞I/O c. ...
- netty学习(一)--linux下的网络io模型简单介绍
linux的内核将全部的外部设备都看作一个文件来操作,对一个文件的读写操作会调用内核提供的系统命令 ,返回一个file descriptor(fd.文件描写叙述符).而对一个socket的读写也会有对 ...
- 简述linux同步与异步、阻塞与非阻塞概念以及五种IO模型
1.概念剖析 相信很多从事linux后台开发工作的都接触过同步&异步.阻塞&非阻塞这样的概念,也相信都曾经产生过误解,比如认为同步就是阻塞.异步就是非阻塞,下面我们先剖析下这几个概念分 ...
- Linux中同步与异步、阻塞与非阻塞概念以及五种IO模型
1.概念剖析 相信很多从事linux后台开发工作的都接触过同步&异步.阻塞&非阻塞这样的概念,也相信都曾经产生过误解,比如认为同步就是阻塞.异步就是非阻塞,下面我们先剖析下这几个概念分 ...
随机推荐
- 从零开始,搭建博客系统MVC5+EF6搭建框架(1),EF Code frist、实现泛型数据仓储以及业务逻辑
前言 从上篇30岁找份程序员的工作(伪程序员的独白),文章开始,我说过我要用我自学的技术,来搭建一个博客系统,也希望大家给点意见,另外我很感谢博客园的各位朋友们,对我那篇算是自我阶段总结文章 ...
- ASP.Net MVC Action重定向跳出Controller和Area
1.重定向方法简介 [HttpPost] public ActionResult StudentList( string StudName, string studName, DateTime Bir ...
- ASP.NET MVC对WebAPI接口操作(添加,更新和删除)
昨天<怎样操作WebAPI接口(显示数据)>http://www.cnblogs.com/insus/p/5670401.html 既有使用jQuery,也有使作HttpClient来从数 ...
- ASP.NET Core 开发-中间件(Middleware)
ASP.NET Core开发,开发并使用中间件(Middleware). 中间件是被组装成一个应用程序管道来处理请求和响应的软件组件. 每个组件选择是否传递给管道中的下一个组件的请求,并能之前和下一组 ...
- log4Net(写入日志文件)
这里就简单介绍下log4Net对写入日志文件的一些了解,写入数据库类似,就不在一一介绍了. 首先去log4net下载. 然后我们新建一个控制台应用程序,并引入log4net.dll程序集,log4ne ...
- Javaweb学习笔记——使用Jdom解析xml
一.前言 Jdom是什么? Jdom是一个开源项目,基于树形结构,利用纯java的技术对XML文档实现解析,生成,序列化以及多种操作.它是直接为java编程服务,利用java语言的特性(方法重载,集合 ...
- Linux Cmd Tool 系列之—history & search command history
History cmd is for list Bash's log of the historical cmd you typed 1. List last n commands history n ...
- 1 为什么搭建.Net core下的云开发框架
几年前我组织开发了综合业务管理系统,该系统包含系统门户.业务信息.联系处置.数据查询.指标报表等功能板块,其中涵盖了门户定制.工作流引擎.自定义表单.指标计算.通用数据展示.通用后台服务.用户授权认证 ...
- CSS学习
标签选择器,标签名{},作用于所有此标签. 类选择器, .class{},在标签内定义class="",属图形结构. ID选择器,#ID{}, 在标签内定义id="&qu ...
- navigationController 返回前N个视图
前提是,由N个视图跳转过来的. //返回前n个 NSInteger index=[[self.navigationController viewControllers]indexOfObject:se ...