• Linux内核缓冲技术


    概述


     内核空间与外围设备交换数据,用户空间与内核空间交换数据实际上是非常消耗时间的,应该尽量减少它们之间相互访问的次数,就应用了缓冲技术。其本质就是一次性读取大量数据(顺序读写)进缓冲,当需要数据的时候进入缓冲区读取数据,这样能够大大减少消耗的时候被消耗的时间,所以内核缓冲技术对于文件IO是非常重要的。

     linux中的fopen函数是open函数的封装,fopen使用了FILE结构体保存缓冲数据,在进行read和write的时候减少了用户态和内核态的切换。open没有缓冲,每次读操作都直接从文件系统中获取数据,在进行read和write的时候每次都需要进行内核态和用户态的切换。当顺序访问文件,fopen系列的函数要比直接调用open系列快;如果随机访问文件open要比fopen快。
     在上图中可以看到open每次打开文件都会产生一个结构体file来保存文件的读写信息,即使对于同时打开同一个文件,其结构体信息是不一样的。

    标准IO缓冲区

     1.不缓冲:一旦有数据,立即同步到外部设备。
     2.全缓冲:(普通文件的默认类型);
      a.一旦数据填满了缓冲区,立即同步到外部设备;
      b.程序正常退出时,立即同步到外部设备;
      c.遇到 fflush() 强制同步时,立即同步到外部设备;
      d.关闭文件时,立即同步到外部设备;
      e.读取文件时 , 立即同步到外部设备;
     3.行缓冲:(最多只能缓冲一行)
      a.一旦填满,立即同步到外部设备;
      b.程序正常退出时,立即同步到外部设备;
      c.遇到 fflush() 强制同步时,立即同步到外部设备;
      d.关闭文件时,立即同步到外部设备;
      e.读取文件时 , 立即同步到外部设备;
      f.一旦遇到 ' ' 时, 立即同步到外部设备;

    相关API

    setbuf ( 设置文件流的缓冲区 )
        头文件:
            #include <stdio.h>
        定义函数:
            void setbuf(FILE * stream, char * buf);
        参数分析:
             stream --> 为指定的文件流
             buf --> 自定的缓冲区起始地址 
         无返回
            
    setvbuf ( 设置文件流的缓冲区)
        头文件:
            #include <stdio.h>
        定义函数:
            int setvbuf(FILE * stream, char * buf, int mode, size_t size);
        参数分析:
            stream --> 指定的文件流 
            buf --> 指向自定的缓冲区起始地址
            size --> 为缓冲区大小
            mode --> 有下列几种
                _IONBF 无缓冲 IO
                _IOLBF 以换行为依据的无缓冲 IO
                _IOFBF 完全无缓冲 IO. 如果参数 buf 为 NULL 指针, 则为无缓冲 IO.
        返回值:
            成功返回 0 
            失败返回 非零 , 错误号码会被设置
    

    使用代码

    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    int main()
    {
     
       char buff[1024];
     
       memset( buff, '', sizeof( buff ));
     
       fprintf(stdout, "启用全缓冲
    ");
       setvbuf(stdout, buff, _IOFBF, 1024);
     
       fprintf(stdout, "这里是 runoob.com
    ");
       fprintf(stdout, "该输出将保存到 buff
    ");
       fflush( stdout );
     
       fprintf(stdout, "这将在程序退出时出现
    ");
       fprintf(stdout, "最后休眠五秒钟
    ");
     
       sleep(5);
     
       return(0);
    }
    

    https://www.runoob.com/cprogramming/c-function-setvbuf.html

    总结

     1.通常磁盘上的文件是全缓冲区的;
     2.标准输入和标准输入在指向终端设备时是行缓冲,而指向文件时,则是全缓冲的;
     3.为了尽可能显示错误信息,标准错误是不带缓冲的。

  • 相关阅读:
    24、可靠信号与不可靠信号
    24、sed用法
    26、linux shell常用的几个函数,diff
    21、Posix共享内存
    23、修改vim的tab,使其占4个空格
    25、linux shell常用的几个函数,sort
    Console算法有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13...求出这个数列的前20项之和
    Console算法[for,if]一水仙花数(Water flower)
    Console算法回文数
    Console算法[for,if]有5个人坐在一起,问第五个人多少岁?他说比第4个人大2岁。问第4个人岁数
  • 原文地址:https://www.cnblogs.com/ding-ding-light/p/14157197.html
Copyright © 2020-2023  润新知