缓冲 io 使用 stdio.h 异步吗?
我了解使用 stdio.h
FILE
相对于直接 read()
/write()
的优点之一是缓冲、中断处理等。因此,据我了解,所有 fwrite()
都会被缓冲,直到我执行 fclose()
为止。到目前为止,一切都很好。现在,当我执行 fclose()
时,我会阻塞直到数据刷新到磁盘,还是 fclose()
在将数据移交给操作系统并让它在空闲时刷新到磁盘?
I understand that one of the advantages of using stdio.h
FILE
over direct read()
/write()
is the buffering, interrupt handling, etc. So, as I understand, all the fwrite()
s get buffered up until I do an fclose()
. So far, so good. Now, when I do an fclose()
, will I block until the data is flushed to disk or will the fclose()
return right away after handing the data over to the OS and letting it flush to disk at its leisure?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
有很多级别的缓冲,这取决于操作系统和许多其他因素。
该缓冲区会刷新到文件(或 FILE* 连接到的任何设备)
在普通磁盘文件的情况下,大多数操作系统在内核中都有缓冲,因此刷新
FILE* 缓冲区或多或少涉及从应用程序缓冲区到操作系统内核的内存副本,内核将在闲暇时将其异步写入实际文件,这将导致 fclose() 返回“马上”。
可能存在这样的情况:在将数据复制到操作系统/内核缓冲区之前,操作系统首先必须执行一些内务处理,例如,它可能必须将数据刷新到物理文件以为更多数据腾出空间,在文件中分配空间以确保有空间等等,使其不会立即返回。
简而言之,这取决于情况,而且你无法控制它。通常,您能做的“最好的”就是使用平台相关的 API,它们至少允许您将操作系统缓冲区刷新到物理文件,例如 posix fsync()/fdatasync() API。
There are buffering at many levels, this depends on the OS and many other things.
Typically there's an internal buffer in the FILE* living in your application that is either flushed out to the file (or whichever device the FILE* is connected to)
In the case of an ordinary disk file, most OS have buffering in the kernel, so flushing the
FILE* buffer involves more or less just a copy of memory from the buffer of your application to the OS kernel, and the kernel will take care of writing it to the actual file at its leisure asynchronously, which will cause the fclose() to return "right away".
There could circumstances where the OS first have to do some housekeeping before the data is copied into the OS/kernel buffers, e.g. it might have to flush out data to the physical file to make room for more data, allocate space in the file to ensure there is room and so on, making it not return instantly.
In short, it depends, and you cannot control it. Usually the "best" you can do is use platform dependent APIs that at least allow you to flush the OS buffers to the physical file, such as the posix fsync()/fdatasync() APIs.
您的理解(至少部分)是错误的。
I/O 已缓冲,但缓冲区大小有限制。当缓冲区溢出时,它们将被刷新。此外,许多流都是行缓冲的;当您写入换行符时,缓冲区将被刷新。如果不是这种情况,那么输出到终端将是非常不切实际的,因为程序终止时所有输出都会出现。
我认为调用不一定会阻塞,否则,有些函数会尝试确保底层媒体与写入同步。这通常会产生“级别太低”的问题,并且需要处理软件以及硬件(例如硬盘驱动器)中的高速缓存和缓冲区的复杂性。
Your understanding is (at least partially) wrong.
The I/O is buffered, but there are limits to the buffer sizes. When the buffers overflow, they will be flushed. Also, many streams are line-buffered; when you write a line feed, the buffer is flushed. If this were not the case, outputting to a terminal would be pretty impractical with all output appearing when the program terminates.
I don't think the calls are necessarily blocking otherwise, there are functions that try to make sure the underlying media is synced with the writes for instance. This commonly creates issues where you get "too low-level" and need to deal with the complexities of caches and buffers both the software but also in the hardware for e.g. hard drives.