【问题标题】:Is buffered io using stdio.h async?缓冲 io 是否使用 stdio.h 异步?
【发布时间】:2012-03-11 07:02:33
【问题描述】:

我知道使用stdio.hFILE 而不是直接使用read()/write() 的优势之一是缓冲、中断处理等。所以,据我所知,所有fwrite()s 都会被缓冲直到我做一个fclose()。到目前为止,一切都很好。现在,当我执行fclose() 时,我会阻塞直到数据刷新到磁盘,还是fclose() 在将数据交给操作系统并让它在空闲时刷新到磁盘后立即返回?

【问题讨论】:

  • 在 Linux 上,即使 write 也不能保证数据在物理上位于磁盘上。您需要使用fsync
  • @Banthar 或使用 O_DIRECT 选项。

标签: c asynchronous stdio buffered


【解决方案1】:

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

I/O 已缓冲,但缓冲区大小有限制。当缓冲区溢出时,它们将被刷新。此外,许多流是行缓冲的;当你写一个换行符时,缓冲区被刷新。如果不是这种情况,输出到终端将是非常不切实际的,因为所有输出都会在程序终止时出现。

我认为调用不一定会阻塞,例如,有些函数会尝试确保底层媒体与写入同步。这通常会产生“太低级”的问题,并且需要处理软件以及硬件中缓存和缓冲区的复杂性,例如硬盘。

【讨论】:

    【解决方案2】:

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

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

    • 当内部 FILE* 缓冲区已满时
    • 当您写入换行符时(如果是缓冲的 FILE* 行)
    • 当您关闭文件时*
    • 当你调用 fflush() 时
    • FILE* 也可以是无缓冲的

    对于普通的磁盘文件,大多数操作系统在内核中都有缓冲,所以刷新 FILE* 缓冲区或多或少只涉及从应用程序缓冲区到操作系统内核的内存副本,内核将在空闲时异步将其写入实际文件,这将导致 fclose() 返回“马上”。

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

    简而言之,它取决于你,你无法控制它。通常你能做的“最好的”是使用至少允许你将操作系统缓冲区刷新到物理文件的平台相关 API,例如 posix fsync()/fdatasync() API。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-12
      • 2010-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-08
      • 1970-01-01
      相关资源
      最近更新 更多