linux缓冲区解析

来源:互联网 发布:java开发软件有哪些 编辑:程序博客网 时间:2024/06/14 21:40

1.什么是缓冲区

缓冲区是内存的一部分空间,用缓冲输入输出的数据。缓冲区又分为输入缓冲区和输出缓冲区。缓冲区又被称为缓存.

2.缓冲区存在的意义

主要的意义就是为了提高cpu的效率。
输入端。假如没有缓冲区,我们要从磁盘中读取数据,有几个字符,CPU就要读写几次,CPU是高速率的,而读取是低速率的,这样做会降低CPU的效率。相反如果将数据都存在缓冲区里面,等要读取的时候就可以一次性读取多数的数据。大大地提高了CPU的效率。
输出端。假如要将数据打印出来,打印机是低速的,CPU是高速的。将数据放入缓冲区,避免数据被分为多次打印,就此解放了CPU,使它能去处理其他任务。

3、缓冲区的分类

(1)行缓冲
遇到\n就刷新缓冲区,当在输入和输出中遇到换行符时,执行真正的I/O操作。这时,我们输入的字符先存放在缓冲区,等按下回车键换行时才进行实际的I/O操作。典型代表是键盘输入数据和输出信息到屏幕(标准输入输出例如printf())。
(2)全缓冲
当缓冲区写满以后就会刷新缓冲区。当填满标准I/O缓存后才进行实际I/O操作。全缓冲的典型代表是对磁盘文件的读写(例如fwrite())。
(3)无缓冲
既没有缓冲区,代表是系统调用(例如write());

4、缓冲区的刷新

(1)行缓冲在遇到\n和缓冲区满的时候刷新
(2)全缓冲在缓冲区写满的时候会刷新
(3)进程退出的时候两种缓冲都会由操作系统强制刷新
(4)fflush()函数可刷新缓冲区

5、缓冲区的提供者

首先介绍一下几个概念
(1)系统调用:操作系统直接暴露给用户的接口。
(2)库函数:把系统调用进行二次封装之后给用户使用的结果叫做库函数(封装系统调用,实现相同的复杂逻辑,节省工作量)
(3)因此库函数和系统调用具有层级关系,库函数是系统调用的上层(以f开头的函数如fwrite都是库函数,去掉f如write是系统调用)
(4)系统调用不具有缓冲区,库函数具有缓冲区,而库函数是系统调用的上层,因此,缓冲区是C语言库提供的。具体一点是由库中的文件操作符提贡的

6、实例

    char *buf="hello bit\n";    printf("hello\n");    write(1,buf,strlen(buf));    pid_t id=fork();    if(id==0)    {printf("child,pid:%d,ppid:%d\n",getpid(),getppid());}    else    {        sleep(2);        printf("child,pid:%d,ppid:%d\n",getpid(),getppid());    }

(1)输出结果
这里写图片描述
(2)然后将输出重定向到文件中去
这里写图片描述

比较一下差异,为什么输出到文件中去以后hello就被输出了两回呢?
解析:因为在fork之前调⽤用write,所以其数据只写到标准输
出⼀一次,所以其数据只写到标准输出一次。标准I/O是缓冲的,如果标准输出到终端设备,则它是行缓冲,否则它是全
缓冲。当以交互方式运行该程序时,只得到printf输出的行一次,因为标准输出到终端缓冲区由换行符冲洗。但将标准输出重定向到一个文件时,由于缓冲区是全缓冲,遇到换行符不输出,当调用fork时,其printf的数据仍然在缓冲区中,该数据将被复制到子进程中,该缓冲区也被复制到子进程中。于是⽗父子进程的都有了带改行内容的标准I/O缓冲区,所以每个进程终⽌止时,会冲洗其缓冲区中的数据,得到第⼀一个printf输出两次。

1 0
原创粉丝点击