在数据写入磁盘之前 fwrite 是否会阻塞?
Does fwrite block until data has been written to disk?
fwrite()
是在将要写入磁盘的数据移交给操作系统后return起作用,还是return仅在实际物理写入数据后才起作用return到磁盘?
对于我的情况,我希望这是第一种情况,因为我不想等到所有数据都物理写入磁盘。我希望另一个 OS 线程在后台传输它。
我很好奇 Windows 10 在这种特殊情况下的行为。
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fwrite
使用fwrite()
时,为了提高效率,有几个地方需要缓冲数据:C++运行时缓冲,操作系统文件系统接口缓冲,实际磁盘硬件缓冲。
这些的默认设置是延迟将数据实际物理写入磁盘,直到有实际请求刷新缓冲区,或者在发出写入请求时打开适当的指示器以执行物理写入。
如果您想更改 fwrite()
的行为,请查看 setbuf()
函数 setbuf redirection as well as setbuff()
Linux man page and here is the Microsoft documentation on setbuf()
。
如果您查看底层 Windows CreateFile()
function 的文档,您会看到有许多标志,其中包括关于是否应该进行数据缓冲的标志。
FILE_FLAG_NO_BUFFERING 0x20000000
The file or device is being opened with no system caching for data
reads and writes. This flag does not affect hard disk caching or
memory mapped files.
There are strict requirements for successfully working with files
opened with CreateFile using the FILE_FLAG_NO_BUFFERING flag, for
details see File Buffering.
并查看 Microsoft documentation topic File Buffering。
In a simple example, the application would open a file for write
access with the FILE_FLAG_NO_BUFFERING
flag and then perform a call to
the WriteFile
function using a data buffer defined within the
application. This local buffer is, in these circumstances, effectively
the only file buffer that exists for this operation. Because of
physical disk layout, file system storage layout, and system-level
file pointer position tracking, this write operation will fail unless
the locally-defined data buffers meet certain alignment criteria,
discussed in the following section.
看看这个关于 OS 级别的设置的讨论,看看看起来 Linux https://superuser.com/questions/479379/how-long-can-file-system-writes-be-cached-with-ext4
Does the fwrite(fp,
...)
function return after the data to be written to disk has been handed over to the operating system or does it return only after the data is actually physically written to the disk?
没有。事实上,它甚至(不一定)不会等到数据被移交给 OS —— fwrite 可能只是将数据放入其内部缓冲区并立即 return 而不会实际写入任何内容。
要强制数据到OS,你需要在FILE
指针上使用fflush(fp)
,但这仍然不一定将数据写入磁盘,虽然它通常会排队等待写作。但它不会等待那些排队的写入完成。
所以为了保证数据被写入磁盘,你需要做一个OS级别的调用来等待队列中的写入完成。在POSIX系统上(如Linux),即fsync(fileno(fp))
。您需要研究 Windows 文档以了解如何在 Windows.
上执行等效操作
fwrite()
是在将要写入磁盘的数据移交给操作系统后return起作用,还是return仅在实际物理写入数据后才起作用return到磁盘?
对于我的情况,我希望这是第一种情况,因为我不想等到所有数据都物理写入磁盘。我希望另一个 OS 线程在后台传输它。
我很好奇 Windows 10 在这种特殊情况下的行为。
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fwrite
使用fwrite()
时,为了提高效率,有几个地方需要缓冲数据:C++运行时缓冲,操作系统文件系统接口缓冲,实际磁盘硬件缓冲。
这些的默认设置是延迟将数据实际物理写入磁盘,直到有实际请求刷新缓冲区,或者在发出写入请求时打开适当的指示器以执行物理写入。
如果您想更改 fwrite()
的行为,请查看 setbuf()
函数 setbuf redirection as well as setbuff()
Linux man page and here is the Microsoft documentation on setbuf()
。
如果您查看底层 Windows CreateFile()
function 的文档,您会看到有许多标志,其中包括关于是否应该进行数据缓冲的标志。
FILE_FLAG_NO_BUFFERING 0x20000000
The file or device is being opened with no system caching for data reads and writes. This flag does not affect hard disk caching or memory mapped files.
There are strict requirements for successfully working with files opened with CreateFile using the FILE_FLAG_NO_BUFFERING flag, for details see File Buffering.
并查看 Microsoft documentation topic File Buffering。
In a simple example, the application would open a file for write access with the
FILE_FLAG_NO_BUFFERING
flag and then perform a call to theWriteFile
function using a data buffer defined within the application. This local buffer is, in these circumstances, effectively the only file buffer that exists for this operation. Because of physical disk layout, file system storage layout, and system-level file pointer position tracking, this write operation will fail unless the locally-defined data buffers meet certain alignment criteria, discussed in the following section.
看看这个关于 OS 级别的设置的讨论,看看看起来 Linux https://superuser.com/questions/479379/how-long-can-file-system-writes-be-cached-with-ext4
Does the
fwrite(fp,
...)
function return after the data to be written to disk has been handed over to the operating system or does it return only after the data is actually physically written to the disk?
没有。事实上,它甚至(不一定)不会等到数据被移交给 OS —— fwrite 可能只是将数据放入其内部缓冲区并立即 return 而不会实际写入任何内容。
要强制数据到OS,你需要在FILE
指针上使用fflush(fp)
,但这仍然不一定将数据写入磁盘,虽然它通常会排队等待写作。但它不会等待那些排队的写入完成。
所以为了保证数据被写入磁盘,你需要做一个OS级别的调用来等待队列中的写入完成。在POSIX系统上(如Linux),即fsync(fileno(fp))
。您需要研究 Windows 文档以了解如何在 Windows.