文档章节

UNIX系统的IO模型

 王CHAO
发布于 2016/05/14 15:51
字数 1919
阅读 3
收藏 0
点赞 2
评论 0

IX系统的IO模型

IOUNIX异步IO非阻塞IOIO复用 

 

其实并非原创,只是摘录了Stevens的大作《UNIX网络编程》,写下来,一、加深理解和记忆;二、书是借的,记录一下备忘。感谢臻,借我此书一阅,受益匪浅。

 

6.2 I/O模型

阻塞式I/O

非阻塞式I/O

I/O复用;

信号驱动式I/O

异步I/O

一个输入操作通常包括两个不同的阶段:

1) 等待数据准备好;

2) 从内核向进程复制数据;

对于一个套接字上的输入操作,第一步通常涉及等待数据从网络中到达。当所等待分组到达时,它被复制到内核中的某个缓冲区。第二步就是把数据从内核缓冲区复制到应用进程缓冲区。

6.2.1 阻塞式I/O模型

最流行的I/O模型是阻塞式I/O(blocking I/O)模型,默认情况下,所有套接字都是阻塞的。以数据报套接字作为例子,我们有如图6-1所示的情形。

 

图6-1 阻塞式I/O模型

在图6-1中,进程调用recvfrom,其系统调用直到数据报到达且被复制到应用进程的缓冲区中或者发生错误才返回。我们说进程在从调用recvfrom开始到它返回的整段时间内是被阻塞的。recvfrom成功返回后,应用进程开始处理数据报。

6.2.2 非阻塞式I/O模型

进程把一个套接字设置成非阻塞是在通知内核:当所请求的I/O操作非得把本进程投入睡眠才能完成时,不要把本进程投入睡眠,而是返回一个错误。非阻塞式I/O(notblocking I/O)模型如图6-2所示:

 

图6-2 非阻塞式I/O模型

前三次调用recvfrom时没有数据可返回,因此内核转而立即返回一个EWOULDBLOCK错误。第四次调用recvfrom时已有一个数据报准备好,它被复制到应用进程缓冲区,于是recvfrom成功返回。我们接着处理数据。

当一个应用进程像这样对一个非阻塞描述符循环调用recvfrom时,我们称之为轮询(polling)。应用进程只需轮询内核,以查看某个操作是否就绪。这么做往往耗费大量CPU时间。

6.2.3 I/O复用模型

有了I/O复用(I/O multiplexing),我们就可以调用select或poll,阻塞在这两个系统调用中的某一个上,而不是阻塞在真正的I/O系统调用上。图6-3概括展示了I/O复用模型。

图6-3 I/O复用模型

我们阻塞于select调用,等待数据报套接字变为可读。当select返回套接字可读这一条件时,我们调用recvfrom把所读数据报复制到应用进程缓冲区。

比较图6-3和图6-1,I/O复用并不显得有什么优势,事实上由于使用select需要两个而不是单个系统调用,I/O复用还稍有劣势。使用select的优势在于我们可以等待多个描述符就绪。

与I/O复用密切相关的另一种I/O模型是在多线程中使用阻塞式I/O(我们经常这么干)。这种模型与上述模型极为相似,但它并没有使用select阻塞在多个文件描述符上,而是使用多个线程(每个文件描述符一个线程),这样每个线程都可以自由的调用recvfrom之类的阻塞式I/O系统调用了。

6.2.4 信号驱动式I/O模型

我们也可以用信号,让内核在描述符就绪时发送SIGIO信号通知我们。我们称这种模型为信号驱动式I/O(signal-driven I/O),图6-4是它的概要展示。

 

图6-4 信号驱动式I/O模型

我们首先开启套接字的信号驱动式I/O功能,并通过sigaction系统调用安装一个信号处理函数。改系统调用将立即返回,我们的进程继续工作,也就是说他没有被阻塞。当数据报准备好读取时,内核就为该进程产生一个SIGIO信号。我们随后就可以在信号处理函数中调用recvfrom读取数据报,并通知主循环数据已经准备好待处理,也可以立即通知主循环,让它读取数据报。

无论如何处理SIGIO信号,这种模型的优势在于等待数据报到达期间进程不被阻塞。主循环可以继续执行,只要等到来自信号处理函数的通知:既可以是数据已准备好被处理,也可以是数据报已准备好被读取。

6.2.5 异步I/O模型

异步I/O(asynchronous I/O)由POSIX规范定义。演变成当前POSIX规范的各种早起标准所定义的实时函数中存在的差异已经取得一致。一般地说,这些函数的工作机制是:告知内核启动某个操作,并让内核在整个操作(包括将数据从内核复制到我们自己的缓冲区)完成后通知我们。这种模型与前一节介绍的信号驱动模型的主要区别在于:信号驱动式I/O是由内核通知我们何时可以启动一个I/O操作,而异步I/O模型是由内核通知我们I/O操作何时完成。图6-5给出了一个例子。

 

图6-5 异步I/O模型

我们调用aio_read函数(POSIX异步I/O函数以aio_或lio_开头),给内核传递描述符、缓冲区指针、缓冲区大小(与read相同的三个参数)和文件偏移(与lseek类似),并告诉内核当整个操作完成时如何通知我们。该系统调用立即返回,并且在等待I/O完成期间,我们的进程不被阻塞。本例子中我们假设要求内核在操作完成时产生某个信号。改信号直到数据已复制到应用进程缓冲区才产生,这一点不同于信号驱动I/O模型。

6.2.6 各种I/O模型的比较

图6-6对比了上述5中不同的I/O模型。可以看出,前4中模型的主要区别在于第一阶段,因为他们的第二阶段是一样的:在数据从内核复制到调用者的缓冲区期间,进程阻塞于recvfrom调用。相反,异步I/O模型在这两个阶段都要处理,从而不同于其他4中模型。

 

图6-6 5种I/O模型的比较

6.2.7 同步I/O和异步I/O对比

POSIX把这两个术语定于如下:

同步I/O操作(sysnchronous I/O opetation)导致请求进程阻塞,直到I/O操作完成;

异步I/O操作(asynchronous I/O opetation)不导致请求进程阻塞。

根据上述定义,我们的前4种模型----阻塞式I/O模型、非阻塞式I/O模型、I/O复用模型和信号驱动I/O模型都是同步I/O模型,因为其中真正的I/O操作(recvfrom)将阻塞进程。只有异步I/O模型与POSIX定义的异步I/O相匹配。

本文转载自:http://shenxueliang.iteye.com/blog/1677194

共有 人打赏支持
粉丝 0
博文 5
码字总数 3246
作品 0
东城

暂无文章

idea tomcat 远程调试

tomcat 配置 编辑文件${tomcat_home}/bin/catalina.sh,在文件开头添加如下代码。    CATALINA_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=7829" Idea端配......

qwfys
今天
1
0
遍历目录下的文件每250M打包一个文件

#!/usr/bin/env python # -*- utf-8 -*- # @Time : 2018/7/20 0020 下午 10:16 # @Author : 陈元 # @Email : abcmeabc@163.com # @file : tarFile.py import os import tarfile import thr......

寻爱的小草
今天
1
0
expect同步文件&expect指定host和要同步的文件&构建文件分发系统&批量远程执行命令

20.31 expect脚本同步文件 expect通过与rsync结合,可以在一台机器上把文件自动同步到多台机器上 编写脚本 [root@linux-5 ~]# cd /usr/local/sbin[root@linux-5 sbin]# vim 4.expect#!/...

影夜Linux
今天
1
0
SpringBoot | 第九章:Mybatis-plus的集成和使用

前言 本章节开始介绍数据访问方面的相关知识点。对于后端开发者而言,和数据库打交道是每天都在进行的,所以一个好用的ORM框架是很有必要的。目前,绝大部分公司都选择MyBatis框架作为底层数...

oKong
今天
13
0
win10 上安装解压版mysql

1.效果 2. 下载MySQL 压缩版 下载地址: https://downloads.mysql.com/archives/community/ 3. 配置 3.1 将下载的文件解压到合适的位置 我最终将myql文件 放在:D:\develop\mysql 最终放的位...

Lucky_Me
今天
2
0
linux服务器修改mtu值优化cpu

一、jumbo frames 相关 1、什么是jumbo frames Jumbo frames 是指比标准Ethernet Frames长的frame,即比1518/1522 bit大的frames,Jumbo frame的大小是每个设备厂商规定的,不属于IEEE标准;...

问题终结者
今天
2
0
expect脚本同步文件expect脚本指定host和要同步的文件 构建文件分发系统批量远程执行命令

expect脚本同步文件 在一台机器上把文件同步到多台机器上 自动同步文件 vim 4.expect [root@yong-01 sbin]# vim 4.expect#!/usr/bin/expectset passwd "20655739"spawn rsync -av ro...

lyy549745
今天
1
0
36.rsync下 日志 screen

10.32/10.33 rsync通过服务同步 10.34 linux系统日志 10.35 screen工具 10.32/10.33 rsync通过服务同步: rsync还可以通过服务的方式同步。那需要开启一个服务,他的架构是cs架构,客户端服务...

王鑫linux
今天
1
0
matplotlib 保存图片时的参数

简单绘图 import matplotlib.pyplot as pltplt.plot(range(10)) 保存为csv格式,放大后依然很清晰 plt.savefig('t1.svg') 普通保存放大后会有点模糊文件大小20多k plt.savefig('t5.p...

阿豪boy
今天
3
0
java 8 复合Lambda 表达式

comparator 比较器复合 //排序Comparator.comparing(Apple::getWeight);List<Apple> list = Stream.of(new Apple(1, "a"), new Apple(2, "b"), new Apple(3, "c")) .collect(......

Canaan_
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部