【Linux】缓冲区的理解

接着上篇【Linux】文件操作|文件描述符|重定向

什么是缓冲区?

我们口中说的缓冲区,一般指的是用户级语言层面给我们提供的缓冲区。本质就是一段内存。
具体在C语言文件操作的中FILE结构体中。它内部不仅有文件描述符fd还有缓冲区。

为什么要有缓冲区?

比如我们从磁盘里取信息,我们先把读出的数据放在缓冲区,计算机再直接从缓冲区中取数据,等缓冲区的数据取完后再去磁盘中读取,这样就可以减少磁盘的读写次数,再加上计算机对缓冲区的操作大大快于对磁盘的操作,故应用缓冲区可大大提高计算机的运行速度。

缓冲区就是一块内存区,它用在输入输出设备和CPU之间,用来缓存数据。它使得低速的输入输出设备和高速的CPU能够协调工作,避免低速的输入输出设备占用CPU,解放出CPU,使其能够高效率工作。

缓冲区刷新策略

缓冲区会结合具体的设备,制定适合自己的刷新策略。
1.立即刷新,无缓冲。
2.行刷新,行缓冲。
一般是在显示器上,因为要适应我们人类的阅读习惯。从左到右。一次阅读。 而不是一次刷新一大片。这样不方便阅读。
3.缓冲区已经满了,这时就要全缓冲。
一般对应的是磁盘文件。

其他情况:
1.用户强制刷新。
2.进程退出时要进行缓冲区刷新。

请看下面代码:

#include <stdio.h>
#include <string.h>
#include <unistd.h>

int main()
{
    // C接口
    printf("hello printf\n");
    fprintf(stdout, "hello fprintf\n");
    const char *fputsString = "hello fputs\n";
    fputs(fputsString, stdout);


    // 系统接口
    const char *wstring = "hello write\n";
    write(1, wstring, strlen(wstring));

    
    fork(); // fork

    return 0;
}

运行结果:
在这里插入图片描述
解释:
代码结束之前,进行创建子进程

  1. 如果我们没有进行重定向>,看到了4条消息,stdout 默认使用的是行刷新,在进程fork之前,三条C语言函数已经将数据进行打印输出到显示器上(外设),FILE内部的缓冲区中已经不存在对应的数据了。
  2. 如果我们进行了重定向>, 写入的文件不再是显示器stdout,而是普通文件,采用的刷新策略是全缓冲,之前的3条c语言函数虽然带了\n,但不足以将普通文件的缓冲区写满!数据并没有被刷新,就是现在缓冲区里还存在未被刷新的数据。
    执行fork创建子进程之后, 子进程把缓冲区的整体复制了一份,然后紧接着就是return 0 进程退出!谁先退出,一定要进行缓冲区刷新,那么这时候缓冲区就要被修改了,OS为了保证进程独立性,就要进行写时拷贝,所以数据最终会显示两份。
  3. write为什么没有打印两次呢?上面的过程都和wirte无关,wirte是系统调用,没有结构体指针FILE,用的是fd,就没有C提供的缓冲区,就不存在缓冲区被修改的问题。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

有效的放假者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值