zoukankan      html  css  js  c++  java
  • 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.为了尽可能显示错误信息,标准错误是不带缓冲的。

  • 相关阅读:
    Oracle中优化SQL的原则(转贴)
    Oracle的分页查询
    Oracle中存储过程和Sql语句的优化重点
    oracle中sql语句的优化
    Oracle中优化SQL的原则(转贴)
    Oracle group by 用法实例详解
    Oracle中group by用法
    一本超越期待的 C++ 书——简评《Boost程序库完全开发指南:深入C++“准”标准库》
    以小见大——那些基于 protobuf 的五花八门的 RPC(2)
    BizTalk请求JAVA的Web Service报错
  • 原文地址:https://www.cnblogs.com/ding-ding-light/p/14157197.html
Copyright © 2011-2022 走看看