一图以蔽之。
标准 I/O
标准 I/O为了提高读写效率和保护磁盘,使用了页缓存机制,不过由于页缓存处于内核空间,不能被应用程序直接寻址,所以还需要将页缓存数据再拷贝到内存对应的用户空间中。这样,需要两次数据拷贝才能完成用户进程对数据的读取操作。写操作也是一样,将页缓存的数据写入磁盘的时候,必须先拷贝到内核空间对应的主存,然后在写入磁盘中。具体如下:
- 调用read()时,如 操作系统内核地址空间的page cache有数据就读取出该数据并直接返回给应用程序,如果没有就从磁盘读取数据到page cache,然后再从页缓存拷贝到应用程序的地址空间;
- 调用write()时,数据会先从应用程序的地址空间拷贝到操作系统内核地址空间的page cache,然后再写入磁盘。
mmap
mmap会减少一层数据从用户地址空间到操作系统地址空间的复制开销 。使用mmap函数的时候,会在当前进程的用户地址空间中开辟一块内存,这块内存与系统的文件进行映射。对其的读取和写入,会转化为对相应文件的操作。 并且会将变化的内容(脏页)自动回写到对应的文件里面。
Direct I/O
凡是通过直接 I/O 方式进行数据传输,数据均直接在用户地址空间的缓冲区和磁盘之间直接进行传输,中间少了页缓存的支持。操作系统层提供的缓存往往会使应用程序在读写数据的时候获得更好的性能,但是对于某些特殊的应用程序,比如说数据库管理系统这类应用,他们更倾向于选择他们自己的缓存机制,因为数据库管理系统往往比操作系统更了解数据库中存放的数据,数据库管理系统可以提供一种更加有效的缓存机制来提高数据库中数据的存取性能。
参考链接
浅谈Buffer I/O 和 Direct I/O
02 基础篇 | Page Cache是怎样产生和释放的?