6. I/O处理方式(5种I/O模型)

6.1 几个概念的辨析

(1)同步和异步

  ①是访问数据的方式,主要是针对IO(资源、数据)而言的。关键在于I/O操作完成后,有没有提供通知机制。

  ②同步的IO,要求进(线)程主动去读写数据,在读写过程还是会阻塞。而异步I/O操作时,进程不主动读写数据,而是内核完成数据读写完成以后将通知进(线)程。

(2)阻塞和非阻塞

  ①是针对进(线)程而言的,进程要访问的数据是否就绪,是否需要等待。

  ②阻塞与非阻塞是针对同步应用而言的。IO操作分为两个阶段:等待数据和数据从内核到用户态的拷贝。对于阻塞,这两个阶段进(线)程都会被阻塞,而非阻塞的IO操作,在第1阶段可能采用轮询方式而不阻塞,但第2阶段的数据拷贝仍然是阻塞的。

(3)生活中的例子:老张烧开水

  ①老张把水壶(普通水壶)放到火上,并等待水开(同步阻塞

  ②老张把水壶(普通水壶)放在火上,去客厅看电视,时不时到厨房看看水开没有。(同步非阻塞

  ③老张把响水壶放到火上,等待水开(异步阻塞,换了一个具有通知功能的响水壶,但老张还是比较傻,只干一件事,就是等待,所以这种模式一般意义不大。)

  ④老张把响水壶放在火上,去客厅看电视,水壶响之前不再去看它,响了再去提壶(异步非阻塞

【小结】

  ①所谓同步、异步是对于水壶而言的普通水壶,同步;响水壶,异步。同步只能让调用者去轮询,看看水壶开了没有。而异步的响水壶在水开后会提醒老张去提壶。

  ②所谓的阻塞、非阻塞,仅仅对于老张而言等待的老张,阻塞,这时可能媳妇喊他都不知道。看电视的老张,而非阻塞的。

6.2 五种I/O模型

(1)阻塞I/O模型:若所调用的I/O函数没有完成相关的功能就会使进程挂起,直到相关数据到达才会返回。如:终端、网络设备的访问。整个过程分为两个阶段:

  ①阶段一是等待数据就绪,网络I/O的情况就是等待远端数据陆续抵达;磁盘I/O的情况就是等待磁盘数据从磁盘上读取到内核态内存中。

  ②阶段二是数据拷贝,出于系统安全,用户态的程序没有权限直接读取内核态内存,因此内核负责把内核态内存中的数据拷贝一份到用户态内存中。理解这两个阶段非常重要,后续I/O模型的演变都是针对这两个阶段进行不同改造。

(2)非阻塞模型:当请求的I/O操作不能完成时,则不让进程休眠,而且返回一个错误。如open、read和write访问。

  ①阶段一频繁轮询的话,也很耗费CPU时间这种方式对单个I/O请求意义不大,但给I/O多路复用铺平了道路。 低速系统调用时,进程可能会阻塞。

  ②非阻塞I/O操作(open、read、write)不阻塞,如果操作不能完成,则出错返回

  ③设定非阻塞的方式:使用open打开文件,设置O_NONBLOCK标志。如果一个文件己经打开,则使用fcntl修改文件状态标志。

(3)I/O多路转接模型:如果请求的I/O操作阻塞,且他不是真正阻塞I/O,而且让其中的一个函数等待,在这期间,I/O还能进行其他操作。如:select函数。

  ①调用 select/poll该方法由一个用户态线程负责轮询多个sockets,直到某个阶段一的数据就绪,再通知实际的用户线程执行阶段二的拷贝。

  ②通过一个专职的用户态线程执行非阻塞I/O轮询,模拟实现了阶段一的异步化。

(4)信号驱动I/O模型:在这种模型下,通过安装一个信号处理程序,系统可以自动捕获特定信号的到来,从而启动I/O。(类似于观察者模式)。阶段一演变为异步,由内核托管,应用程序只需告知内核,当阶段一数据就绪时向应用程序发出 SIGIO信号。至此为止,前述4种模型的阶段二仍是处于block状态的

(5)异步I/O模型:在这种模型下,当一个描述符己准备好,可以启动I/O时,进程会通知内核。由内核进行后续处理。当整个过程(包括阶段一和阶段二)全部完成时,通知应用程序来读数据。这种用法现在较少。

6.3 五种模型的比较

【编程实验】非阻塞I/O的read调用。

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include "io.h" int main(void)
{
char buffer[] = {};
ssize_t size = ; //默认,IO是阻塞的,后面的read会阻塞等待键盘输入。
//以下演示非阻塞IO的读取。
set_fl(STDIN_FILENO, O_NONBLOCK); sleep(); size = read(STDIN_FILENO, buffer, sizeof(buffer)); if(size < ){
perror("read error");
exit();
}else if (size == ){
printf("read finished\n");//进程执行过程中,在没有键盘输入并按ctrl+D
//会执行到这里。
}else{
if(write(STDOUT_FILENO, buffer, size) != size){
perror("write error");
exit();
}
} return ;
}

第3章 文件I/O(5)_五种I/O模型的更多相关文章

  1. Flume环境搭建_五种案例

    Flume环境搭建_五种案例 http://flume.apache.org/FlumeUserGuide.html A simple example Here, we give an example ...

  2. Flume环境搭建_五种案例(转)

    Flume环境搭建_五种案例 http://flume.apache.org/FlumeUserGuide.html A simple example Here, we give an example ...

  3. Unix网络编程中的五种I/O模型_转

    转自:Unix网络编程中的的五种I/O模型 下面主要是把unp第六章介绍的五种I/O模型. 1. 阻塞I/O模型 例如UDP函数recvfrom的内核到应用层.应用层到内核的调用过程是这样的:首先把描 ...

  4. perl5 第五章 文件读写

    第五章 文件读写 by flamephoenix 一.打开.关闭文件二.读文件三.写文件四.判断文件状态五.命令行参数六.打开管道 一.打开.关闭文件   语法为open (filevar, file ...

  5. 零基础学Python--------第10章 文件及目录操作

    第10章 文件及目录操作 10.1 基本文件操作 在Python中,内置了文件(File)对象.在使用文件对象时,首先需要通过内置的open() 方法创建一个文件对象,然后通过对象提供的方法进行一些基 ...

  6. apue学习笔记(第三章 文件I/O)

    本章开始讨论UNIX系统,先说明可用的文件I/O函数---打开文件.读写文件等 UNIX系统中的大多数文件I/O只需用到5个函数:open.read.write.lseek以及close open函数 ...

  7. 第四章 文件的基本管理和XFS文件系统备份恢复 随堂笔记

    第四章 文件的基本管理和XFS文件系统备份恢复 本节所讲内容: 4.1 Linux系统目录结构和相对/绝对路径. 4.2 创建/复制/删除文件,rm -rf / 意外事故 4.3 查看文件内容的命令 ...

  8. 20190903 On Java8 第十七章 文件

    第十七章 文件 在Java7中对 文件的操作 引入了巨大的改进.这些新元素被放在 java.nio.file 包下面,过去人们通常把nio中的n理解为new即新的io,现在更应该当成是non-bloc ...

  9. linux文件内容列传行_行转列

    ================ 文件内容列传行_行转列  ================ 一.列转行 1.编辑测试文件 vi log.txt 16:23:00 8.2% 1773620k 16:2 ...

随机推荐

  1. Femtocell家庭基站通信截获、伪造任意短信漏洞

    阿里移动安全团队与中国泰尔实验室无线技术部的通信专家们一起,联合对国内运营商某型Femtocell基站进行了安全分析,发现多枚重大漏洞,可导致用户的短信.通话.数据流量被窃听.恶意攻击者可以在免费申领 ...

  2. ifstream 和 ofstream 用法。

    outfile << pContent;//不可以用这个,因为不能写完全,比如遇到字符串中出现/0就终止了 bool CTestEn_DecryptDLLDlg::WriteDataFil ...

  3. SWIFT模糊效果

    首先创建一个模糊效果 let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.Light) 接着创建一个承载模糊效果的视图let blurView ...

  4. Magento里显示指定分类的所有子分类

    如何在magento左侧导航栏里显示父分类和子分类名,如果需要在magento显示指定分类的所有子分类,可以用以下的方法: <!--? php   if($category--->hasC ...

  5. spark中saveAsTextFile如何最终生成一个文件

    原文地址: http://www.cnblogs.com/029zz010buct/p/4685173.html 一般而言,saveAsTextFile会按照执行task的多少生成多少个文件,比如pa ...

  6. Mongodb $setOnInsert操作符 和upsert:true

    upsert:true:如果要更新的文档不存在的话会插入一条新的记录 $setOnInsert操作符会将指定的值赋值给指定的字段,如果要更新的文档存在那么$setOnInsert操作符不做任何处理: ...

  7. with() {} 的用法

    var use = "other"; var katana = { isSharp: true, use: function(){ this.isSharp = !!this.is ...

  8. HDU 2647:Reward(拓扑排序+队列)

    Reward Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  9. HihoCoder - 1051:补提交卡

    时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho给自己定了一个宏伟的目标:连续100天每天坚持在hihoCoder上提交一个程序.100天过去了,小Ho查看自己的提交 ...

  10. 利用GPU改善程序性能的一点心得

    1.     硬件方面 a. 流处理器个数    Gpu内部的计算单元个数,决定分析模块实时性的关键因素.    实测效果: gtx760  1152个 Gtx960  1024个 单路1080p运动 ...