Buffer
缓冲区(Buffer)就是在内存中预留指定大小的存储空间用来对输入/输出(I/O)的数据作临时存储,这部分预留的内存空间就叫做缓冲区:
使用缓冲区有这么两个好处:
1、减少实际的物理读写次数
2、缓冲区在创建时就被分配内存,这块内存区域一直被重用,可以减少动态分配和回收内存的次数
I/O缓冲
从图中自上而下,首先是通过stdio库将用户数据传递到stdio缓冲区,该缓冲区位于用户态内存区。当缓冲区填满时,stdio库会调用write()系统调用,将数据传递到内核高速缓冲区(位于内核态内存区)。最终,内核发起磁盘操作,将数据传递到磁盘。
图左侧所示为可于任何时刻显式强制刷新各类缓冲区的调用。
图右侧所示为促使刷新自动化的调用:一是通过禁用stdio库的缓冲,二是在文件输出类的系统调用中启用同步,从而使每个write()调用立刻刷新到磁盘。
直接I/O
调用open()打开文件或设备时指定O_DIRECT标志可以绕过缓冲区,直接对磁盘进行读写。
内核针对缓冲区高速缓存做了不少优化,其中包括:按顺序预读取,在成簇(clusters)磁盘块上执行I/O,允许访问同一文件的多个进程共享高速缓存的缓冲区。
如果使用直接读写,将无法享受这些优势。
因为直接I/O(针对磁盘设备和文件)涉及对磁盘的直接访问,所以在执行I/O时,必须遵守一些限制。
- 用于传递数据的缓冲区,其内存边界必须对齐为块大小的整数倍。
- 数据传输的开始点,亦即文件和设备的偏移量,必须是块大小的整数倍。
- 待传递数据的长度必须是块大小的整数倍
批注:缓冲区包括stdio缓冲区(buffer)和内核的高速缓冲区(cache),即