Buffer IO、Direct IO与mmap

Buffer IO、Direct IO与mmap_第1张图片

1. Buffer IO

普通的IO读写,一般会经过 用户态内存--> PageCache--> FileSystem--> Block IO。

代码层面,读写的流程:

  • malloc: 申请用户态内存;
  • fwrite: 写入用户态内存;
  • flush: 将用户态内存flush到内核态的PageCache;

    • 内核态的PageCache会被异步的写入disk;
    • 可通过sync()系统调用,同步的将PageCache写入disk;
{
    char *buf = malloc(MAX_BUF_SIZE);    //申请app内的buffer
    strncpy(buf, src, , MAX_BUF_SIZE);
    fwrite(buf, MAX_BUF_SIZE, 1, fp);    //写入app的buffer
    fflush(fp);    //将app的buffer刷入kernel的page cache
}

2. Direct IO

Direct IO不经过内核的PageCache,多用于数据库的场景,比如MySQL。

这类上层的应用通常需要自己管理I/O的读写缓存,它比内核更了解哪些数据该换入换出,在读写流程上一般会经过FileSystem向设备IO请求读写。

3. mmap

mmap将PageCache映射到用户的虚拟内存地址,用户代码可以直接以内存访问的方式,通过Page fault与内核交互。

mmap的特点:

  • 读文件时,减少了一次PageCache--->用户态内存的COPY;
  • 若文件的更新操作较多,会触发大量的脏页回写到disk,引发随机I/O,所以在随机写的场景下,mmap的效率不一定比Buffer IO高;
  • mmap对变长的文件不适合:对变长的文件,需要频繁的申请或回收内存,引发Page Fault;
  • mmap对小文件不适合:因为内存页最小是4KB,若整个映射到PageCache,会造成内存浪费;

参考:

1.https://www.zhihu.com/question/265246208
2.https://www.jianshu.com/p/755338d11865

你可能感兴趣的:(linuxi-o)