操作系统如何对文件执行缓冲

Met*_*est 3 c linux operating-system

我知道,当您调用fwrite或者fprintf更确切地说任何其他写入文件的函数时,内容不会立即刷新到磁盘,而是缓冲在内存中。

首先,操作系统在哪里管理这些缓冲区以及如何管理。其次,如果您对文件进行写入,然后读取您写入的内容,并假设操作系统在写入和读取之间没有刷新内容,那么它如何知道它必须从缓冲区返回读取的内容?对于这种情况它是如何处理的呢。

我想知道这一点的原因是我有兴趣在用户空间中实现我自己的缓冲方案,而不是像操作系统那样在内核空间中实现。也就是说,对文件的写入将在用户空间中进行缓冲,并且实际写入只会在某个时刻发生。因此,我还需要处理对仍在缓冲区中的内容调用 read 的情况。是否可以在用户空间中完成所有这些操作?

cni*_*tar 5

\n

首先,操作系统在哪里管理这些缓冲区以及如何管理

\n
\n\n

这些函数fwritefprintf使用的 stdio 缓冲区已经完全位于用户空间中。缓冲区(可能)是静态数组或可能是分配的内存。

\n\n
\n

它如何知道必须返回从缓冲区读取的内容

\n
\n\n

事实并非如此,因此看不到更改。在调用底层系统调用 ( ) 之前,文件实际上不会发生任何事情write(即使如此 - 继续阅读)。

\n\n
\n

是否可以在用户空间中完成所有这些操作

\n
\n\n

不,这是不可能的。好消息是内核已经有缓冲区,因此您所做的每件事write实际上都不会转换为对文件的实际写入。它被推迟并稍后执行。如果与此同时有人试图从文件中读取数据,内核就会足够聪明地从缓冲区中为他提供服务。

\n\n

来自 TLPI 的位:

\n\n
\n

使用磁盘文件时,read() 和 write() 系统调用\n don\xe2\x80\x99t 直接启动磁盘访问。相反,它们只是在用户空间缓冲区和内核缓冲区高速缓存中的缓冲区之间复制数据。

\n\n

当对磁盘文件执行 I/O 时,从 write() 成功返回并不能保证数据已传输到磁盘,因为内核按顺序对磁盘 I/O 进行缓冲减少磁盘活动并加快 write() 调用。稍后,内核会将其缓冲区写入(刷新)磁盘。

\n\n

如果在此期间,另一个进程尝试读取文件的这些字节,则内核会自动从缓冲区高速缓存提供数据,而不是从文件(的过时内容)提供数据。

\n
\n\n

所以您可能想了解syncfsync

\n\n

多级缓冲通常是不好的。缓冲区有用的原因stdio是它们可以最大限度地减少执行的系统调用数量。如果系统调用更便宜,那么就没有人会再使用 stdio 缓冲区了。

\n