2012-02-20 65 views
2

据我了解,使用stdio.hFILE比直接read()/write()的优势之一是缓冲,中断处理等,所以,据我所知,所有的fwrite()小号得到缓冲,直到我做一个fclose()。到现在为止还挺好。现在,当我做一个fclose()时,我会阻塞,直到数据刷新到磁盘或fclose()将数据交给操作系统后立即返回,并让它闲置时刷新到磁盘?使用stdio.h异步缓冲io?

+0

在Linux上,即使'write'也不能保证数据在物理上位于磁盘上。您需要使用[fsync](http://linux.die.net/man/2/fsync)。 – 2012-02-21 09:38:56

+0

@Banthar或使用O_DIRECT选项。 – 2012-02-21 10:53:18

回答

3

有很多级别的缓冲,这取决于操作系统和许多其他的东西。

通常有一个在FILE *活在你的应用程序,要么刷新到该文件的内部缓冲区(或任何设备的文件*连接)

  • 当内部FILE *缓冲区已满
  • 当你写一个换行符(在一条线上缓冲FILE *的情况下)
  • 当您关闭FILE *
  • 当你调用fflush()
  • 的FILE *也可以缓冲

在一个普通的磁盘文件的情况下,大多数操作系统具有缓冲的内核,所以冲洗 FILE *缓冲区涉及或多或少只是从你的应用程序的缓冲存储器复制到操作系统内核,内核会照顾它在异步时将其写入实际文件,这将导致fclose()立即返回。

在数据被复制到操作系统/内核缓冲区之前,操作系统首先必须做一些清洁工作,例如,它可能需要将数据刷新到物理文件以腾出更多数据,在文件中分配空间以确保存在空间等等,使其不会立即返回。

简而言之,它取决于,而你无法控制它。通常,您可以使用的“最佳”方法是使用平台相关的API,它们至少允许您将OS缓冲区刷新到物理文件,例如posix fsync()/ fdatasync()API。

0

你的理解是(至少部分)错误的。

I/O被缓冲,但缓冲区大小有限制。当缓冲区溢出时,它们将被刷新。另外,许多流是行缓冲;当您编写换行符时,缓冲区将被刷新。如果情况并非如此,输出到终端对于程序终止时所有输出显示都是不切实际的。

我认为这些调用不一定会被阻塞,否则有一些函数会尝试确保底层介质与写入同步。这通常会造成“太低级”的问题,需要处理高速缓存和缓存这两种软件的复杂性,而且还需要在硬件中处理这些问题。硬盘驱动器。