参考:http://blog.csdn.net/shrdlu/article/details/48929865

其实对于计算机器的理解,难点是为什么会有这个模型的建立,也就是模型建立的实际意义,另外还有一点,这个模型的形象化表示,如果能理解这个模型的形象化表示,就可以更深刻的理解模型。
网络或者书籍往往不能这样去解释模型的意义以及模型的形象化表示,所以学习计算机的初期,你或许会有点进步,但是学到最后往往会很迷茫,这时候有个导师帮助你显得尤为重要。

个人以前并没有深入去研究输入输出模型,但是,网络编程却使用了这个模型,导致在做数据传输的时候各种迷茫,只能退到C语言的层面,了解C语言的基本输入输出模型,因为soket描述符其实就是一个文件描述符,但是这个描述符有其特殊的意义,但是,这个描述符的输入输出模型和一般性的文件描述符都是类似的。

先给出模型图,稍后再解释这个模型图:

这篇文章会很长,因为需要解释的东西很多,希望大家有耐心的读下去,我保证所有的内容都是些基本的概念(但是我不保证概念的正确性,毕竟这是个人见解,又没有做事实论证,我的目的是你能够理解输入输出模型形象化的表示,至于理解的过程因人而异),有些概念如果有疑问,请留言,我会直接测试一下。如果可以的话,我会对概念进行测试。使用的操作系统是centos6/centos7(内核是linux, 不使用windows的原因是我个人正在研究《UNIX网络编程》)。

首先,大部分的输入输出模型就是上图所展示的,部分输入输出模型是上图的简化,其余的我暂时没有概念。

我们先来描述这个模型图,然后解释每个组成部分的意义(这些都是个人的见解,不一定对,但是绝对有参考价值)。

“设备”其实就是文件描述符所指定的东西,这个“设备”对应LINUX操作系统就是文件(一切皆文件),对应实际的物理设备就是硬盘、网卡、键盘、显示器等等。我们为了理解上的方便,暂时定义这个“设备”就是“文件”。

“输出缓冲区”与“输入缓冲区”这部分对应操作系统来说一般就是“内存”这个物理设备,但是,我们不关心他的具体形式,我们关心的是,“代码”部分可以直接对这部区域进行读或写,那么问题来了,“代码”部分能不能直接对“设备”读或写呢?答案是肯定的。既然可以直接读写“设备”,为什么还要有“输入输出缓冲区”呢?这个我后文进行阐述,这也是整个模型理解起来最困难的地方。

“代码”部分就是我们C语言编辑的部分,这部分对于程序员来说是可见的部分。

“A”过程是把“设备”的内容写入到“输入缓冲区”,对应的操作系统API是“read”(低级I/O)。

“B”过程是把“输入缓冲区”的内容写入“代码”,对应的标准库API是“getc”等(高级I/O)

“C”过程是把“代码”的内容写入到“输出缓冲区 ”,对应的标准库API是“putc”等(高级I/O)

“D”过程是把“输出缓冲区”写入到“设备”, 对应的操作系统API是“write”(低级I/O)

对于实际的实现,“输入输出缓冲区”部分还有一些特性,我们忽略这个特性,我们简单的模拟一下,代码是如何实现读的操作的,我们以标准输入stdin做为例子。
我们在终端部分输入一个内容,当我们按下回车的时候,操作系统唤醒代码的读取代码(比如我们正在等待getc),假设我们的输入时“abcd回车”,然后这个内容就首先会写入到输入缓冲区(A过程),假设输入缓冲区足够的大,那么“abcd回车”就会全部写入到“输入缓冲区”,接着就会写入到代码(B过程),这时候我们的代码紧紧消费了一个字符“a”,输入缓冲区还有“bcd回车”等,如果我们再次调用getc,我们的紧紧会执行B过程,这时候的getc也不会阻塞,因为输入缓冲区是有数据的而且是足够的,如果我们持续消费,导致输入缓冲区为空,我们再次使用getc函数,这时候getc函数就会阻塞,等待唤醒,整个过程就会重复。(个人没有代码实践,可以的话最好使用代码实验一下)

stdout拥有类似的过程,但是这还是有些不一样,C过程的部分就是putc所做的工作,D过程是write控制的,这部分一般会有两个问题,D过程是否可能会阻塞?答案是肯定的,D过程可能会阻塞的,比如网卡设备的写,如果使用TCP协议,TCP协议是有流量控制的,这时候D过程就会阻塞。D过程什么时候执行?一般有两种方式,一种是自动的,比如设置一个条件,当“输出缓冲区”满的时候,执行D过程,还有一种方式是手动的,比如我们可以执行fflush()方法,或者执行fclose()方法,这些方法就会执行D过程。

如果能够理解上面所说的流程方式,我在说下,我对“输入输出缓冲区”的理解,这部分有几个好处:

  1. 我们可以屏蔽掉低级I/O的实现,低级I/O的实现依赖操作系统本身内核的实现,所以如果能够屏蔽这部分的差异,我们可以很容易写出可移植的程序。
  2. 我们可以使用这部分的内容实现“行”读取的行为,对于计算机而言是没有“行”这个概念,有了这部分,我们可以定义“行”的概念,然后解析缓冲区的内容,返回一个“行”。

这里有个设计性的问题,如果我们想屏蔽设备的差异性,而设备之间又有某些相同的特性(比如都是关系数据库),那么我们就可以利用上面的模型,建立一个“缓冲区”层,这样代码部分只针对“缓冲区”层进行设计。另外,我们还会发现,当我们使用getc的时候,我们还是需要一个文件描述符号,而文件描述符是针对设备的,也就是,不论我们怎么设计代码,上层的代码必须告诉底层我需要从什么设备读或者写操作,我们可以使用类似“文件描述符”的概念去执行这个通知的操作,但是,你还是必须告诉底层,你到底想干什么才行。“缓冲区”层只是屏蔽具体的读或写的具体方式,但是没有屏蔽掉设备本身的差异性。

这部分的内容对于《UNIX网络编程》很有参考意义。因为对于网卡的读或者写,我们是没有“缓冲区”层的,标准库并没有支持这部分内容,所以我们只能依赖A和D过程。另外,网络编程的I/O输入设备往往不是单一的,可能是标准输入设备和网卡设备同时操作(交互性的程序),这时候,我们往往不能使用标准库的函数,因为“缓冲区”层对于不是内核的任务,如果有这一层可能会增加代码的复杂度。简单的说,如果你想写一个“读行”这个行为,其实是很困难的,因为你不能把使用缓冲层,就只能从设备依次读取单个字符,而这个过程是低效的,从设备读我们往往使用块的方式。

C语言的输入输出模型相关推荐

  1. R语言构建xgboost模型:控制训练信息输出级别verbose参数

    R语言构建xgboost模型:控制训练信息输出级别verbose参数 目录 R语言构建xgboost模型:控制训练信息输出级别verbose参数

  2. R语言构建回归模型并进行模型诊断(线性关系不满足时)、进行变量变换(Transforming variables)、使用car包中的boxTidwell函数对预测变量进行Box–Tidwell变换

    R语言构建回归模型并进行模型诊断(线性关系不满足时).进行变量变换(Transforming variables).使用car包中的boxTidwell函数对预测变量进行Box–Tidwell变换 目 ...

  3. R语言构建xgboost模型:基于稀疏数据(dgCMatrix which is a sparse matrix)、稠密数据(dense matrix)、xgb.DMatrix数据聚合

    R语言构建xgboost模型:基于稀疏数据(dgCMatrix which is a sparse matrix).稠密数据(dense matrix) 目录

  4. R语言构建xgboost模型:使用xgb.DMatrix保存、加载数据集、使用getinfo函数抽取xgb.DMatrix结构中的数据

    R语言构建xgboost模型:使用xgb.DMatrix保存.加载数据集.使用getinfo函数抽取xgb.DMatrix结构中的数据 目录

  5. R语言使用线性回归模型来预测(predict)单个样本的目标值(响应值、response)实战

    R语言使用线性回归模型来预测(predict)单个样本的目标值(响应值.response)实战 目录

  6. R语言随机森林模型:计算随机森林模型的特征重要度(feature importance)并可视化特征重要度、使用少数重要特征拟合随机森林模型(比较所有特征模型和重要特征模型在测试集上的表现差异)

    R语言随机森林模型:计算随机森林模型的特征重要度(feature importance)并可视化特征重要度.使用少数重要特征拟合随机森林模型(比较所有特征模型和重要特征模型在测试集上的表现差异) 目录

  7. R语言构建xgboost模型:xgb.cv函数交叉验证确定模型的最优子树个数(可视化交叉验证对数损失函数与xgboost模型子树个数的关系)、交叉验证获取最优子树之后构建最优xgboost模型

    R语言构建xgboost模型:xgb.cv函数交叉验证确定模型的最优子树个数(可视化交叉验证对数损失函数与xgboost模型子树个数的关系).交叉验证获取最优子树之后构建最优xgboost模型 目录

  8. R语言构建xgboost模型并评估模型(测试集、训练集每一轮):误分类率指标(misclassification rate)、logloss

    R语言构建xgboost模型并评估模型(测试集.训练集每一轮):误分类率指标(misclassification rate).logloss 目录

  9. R语言构建xgboost模型:模型的特性重要度计算及可视化、模型对应的结构树(文本文件)

    R语言构建xgboost模型:模型的特性重要度计算及可视化.模型对应的结构树(文本文件) 目录

最新文章

  1. 表框mysql_mysql 表的操作
  2. 快速认识网络爬虫与Scrapy网络爬虫框架
  3. 直播 | WWW 2021论文解读:论解耦图卷积网络和标签传播的等价性
  4. oracle 删除空间不足,oracle表空间扩容、创建、删除(解决表空间不足问题)
  5. C#中Split用法
  6. 线段树(单点更新,区间查询) HDU 1754 I Hate It
  7. readelf使用说明
  8. 安信可BT-02 Mesh组网的AT指令集
  9. C++判断一个数是否为素数
  10. 面试题-取出url中的参数以json对象结构输出(JavaScript)
  11. 不知道考研那些书比较好么?我来推荐~~~(一)
  12. android 简单的exoplayer全景播放器
  13. 厦门市各公交线路途经站点
  14. STM32F103单片机驱动TM1637数码管显示模块
  15. 这些网络流行语是什么意思!打工是不可能打工的,这辈子不可能打工的!(来自窃·格瓦拉的名言)
  16. 用paddleocr识别汉字_基于Paddle的截图OCR文字识别的实现
  17. 关于Wav音频压缩MP3
  18. 兄弟5340D更换硒鼓单元
  19. ups计算软件_UPS电源在医疗行业的应用
  20. 产线流量测试解决方案

热门文章

  1. StringRedisTemplate报NullPointerException
  2. 【CAD】通过VBA获取CAD中的文本
  3. PCL voxelgrid实现
  4. 任正非:我们国家还是要强调发展实体经济 发挥工匠精神
  5. 强制将int转化为float
  6. 马原(2023版)哲学基本问题笔记
  7. VQA_v2数据集预处理
  8. {}企业如何利用邮件进行推广?
  9. PS将多个图片合并成长图
  10. 基于Matlab Simulink开发的嵌入式模型,模型可自动生成ccs工程代码,生成的代码可直接运行在主控芯片中