在现代操做系统里几乎全部的I/O设备在和处理机交换数据时都使用了缓冲机制,缓冲区是一个存储区域,能够是专门的硬件寄存器组成可是由于硬件的成本较高容量也小,通常的状况下,更多的利用内存来做为缓冲区。linux
缓冲区管理:组织缓冲区并提供得到和释放缓冲区的手段。小程序
缓冲技术是为了协调吞吐速度相差很大的设备之间数据调用而采用的技术ide
缓冲的引用要解决的问题实际上有:
函数
一、改善CPU和I/O设备之间速度不匹配的状况。学习
二、能够减小I/O设备对CPU的中断次数及放宽对CPU的中断响应时间要求。spa
三、提升CPU和I/O设备之间的并行性
操作系统
eg: 在生产者(CPU)和消费者(打印机)之间设置缓冲区,生产者在生产了一批数据并将其入缓冲区接着投入下一次生产,而消费此时就可拿出数据,这样生产者和消费者就可处于并行的工做状态。若是他们之间没有缓冲区的话,生产者生产好了一批数据以后必须停下工做等待消费者,这样会使得生产者的效率下降。
指针
一、单缓冲区orm
假设数据从I/O设备传递给缓冲区的时间为T,CPU对数据的处理时间是C,缓冲区将数据传送给CPU的时间是M,那么忧郁在I/O设备给缓冲区传送数据时,CPU能够同时处理数据,因此系统对数据处理的总时间为Max(C,T)+M.blog
**在字符设备输入时缓冲区是用于暂存用户输入的一行数据,在输入期间用户进程挂起等待,输出时,用户进程将一行数据输入到缓冲区后继续进行处理,当用户程序已有第二行数据输出可是第一行数据还没有被提取完成则会形成用户进程的阻塞。
2.双缓冲区
双缓冲区其实是为了解决消费者和生产者在使用缓冲区时互斥的问题。若是消费者还没有取走缓冲区的数据,那么即便生产者产生了新数据也没法送入缓冲区
双缓冲又被称为缓冲对换,在设备如属实可将数据先送入第一缓冲区,等到第一缓冲区装满后转向第二缓冲区,此时操做系统就能够从第一缓冲区移出数据送入用户进程,让CPU对数据进行处理。
若是在实现两台机器之间通讯时他们只设置了单缓冲,那么他们之间只能在任一时刻实现单向数据传输,为了实现双向数据传输必须在每一个机器上分别设置发送缓冲区及接收缓冲区。
3.环形缓冲区
环形缓冲区中包含多个缓冲区,其中每一个缓冲的大小相同,而且被分为三种类型:
R:装输入数据
G:已装满数据的缓冲区
C:进程正在使用的缓冲区
环形缓冲区里含有三个指针:
Nexti:指向输入进程下次可用的R
Nxetg:指向计算进程下次可以使用的G
Cuurent:指向进程正在使用的缓冲区
在对环形缓冲区进行处理的时候有两个重要的方法:
1.Getbuf:将指针Nextg指向的缓冲区提供给进程而且让修改current的值,最后让Nextg指向下一个G缓冲区
2.Releasebuf:将使用完成的C缓冲区释放将其修改为R,当R缓冲区满时将其修改成G
环形缓冲区还会出现下面两种问题:
1.系统计算受限:Nexti追上Nextg
2.系统I/O受限:Nextg追上Nexti
缓冲池
咱们在以前所说的缓冲区均可以称为专用缓冲。当系统较大时,为了提升利用率,咱们使用便可输入又可输出的公用缓冲池,在池中设置若干个缓冲区。
缓冲池的组成:
1.空白缓冲队列:空缓冲区所链成
2.输入队列:装满输入数据的缓冲区链成
3.输出队列:装满输出数据的缓冲区链成
缓冲区的工做方式:收容输入、收容输出、提取输入、提取输出
在咱们的学习过程当中你们实际上已经和缓冲很熟悉了可是咱们却视若无睹,咱们知道在linux里有三种缓冲机制,行缓冲,全缓冲,无缓冲。
全缓冲:直到缓冲区填满以后调用系统I/O
行缓冲:直到遇到换行或者行缓冲填满以后进行调用系统I/O
咱们来看两个关于行缓冲的例子:
第一例:神秘消失的hello world
在上面的程序里咱们没有在标准输出里使用‘\n’而且使用了_exit(0)致使行缓冲的内容没有被处理
因此在咱们运行程序时,咱们并无看见hello world
**
exit ()。调用exit函数以后,它首先会执行一系列的清理处理,包括调用执行各终止处理程序,关闭全部标准IO流等,而后进入内核。
_exit ()。与exit不一样的是,它不进行清理工做而直接进入内核。
_Exit ()。一样,它也不进行清理工做而直接进入内核。
第二例:进度条小程
显然在此例里,咱们借助了fflush来刷新咱们的缓冲区,在使用该函数时不管缓冲区是否被填满都会调用系统I/O。
再此咱们须理解换行和回车的不一样概念,换行是指跳到当前行的下一行,而回车是指回到该行的行首,此例中咱们使用了‘\r’来控制每次从行首的覆盖输出实现进度条的前进,是否是很神奇呢,你也快去试一试吧!