我知道当你调用fwrite
或fprintf
或者更确切地说是写入文件的任何其他函数时,内容不会立即刷新到磁盘,而是缓存在内存中。
首先,OS在哪里管理这些缓冲区以及如何管理这些缓冲区。其次,如果您对文件进行写入并稍后读入您编写的内容并假设操作系统在您编写和读取之间没有刷新内容,那么它如何知道它必须从缓冲区返回读取内容?它是如何处理这种情况的。
我想知道这个的原因是我有兴趣在用户空间中实现我自己的缓冲方案,而不是像OS那样在内核空间中实现。也就是说,写入文件将在用户空间中缓冲,实际写入仅在某一点发生。我还需要处理为仍在缓冲区中的内容调用read的情况。是否可以在用户空间中完成所有这些操作。
答案 0 :(得分:4)
首先,操作系统在哪里管理这些缓冲区以及如何
函数fwrite
和fprintf
使用已完全在用户空间中的stdio缓冲区。缓冲区(可能)是静态数组或者可能是malloced内存。
它如何知道必须从缓冲区返回读取
没有,所以看不到变化。在调用底层系统调用(write
)之前,文件实际上没有发生任何事情(即使那时 - 读取)。
是否可以在用户空间中完成所有这些操作
不,这是不可能的。好消息是内核已经有缓冲区所以你所做的每个write
都不会被实际翻译成对文件的实际写入。它被推迟并在以后执行。如果在此期间有人试图从文件中读取内容,那么内核足够聪明,可以从缓冲区中为他提供服务。
来自TLPI的位:
使用磁盘文件时,read()和write()系统调用 不要直接启动磁盘访问。相反,他们只是复制数据 在用户空间缓冲区和内核缓冲区缓存中的缓冲区之间。
在磁盘文件上执行I / O时,从write()成功返回 不保证数据已传输到磁盘,因为 内核执行磁盘I / O缓冲以减少磁盘 活动并加快write()调用。 稍后,内核将其缓冲区写入(刷新) 磁盘。
如果在此期间,另一个进程尝试读取这些字节 该文件,然后内核自动提供数据 缓冲区缓存,而不是文件的(过时内容)。
因此,您可能希望了解sync
和fsync
。
多级缓冲通常很糟糕。 stdio
缓冲区有用的原因是它们最小化了执行的系统调用次数。如果系统调用会更便宜,则不再使用stdio缓冲区。