【问题标题】:non blocking write to file in c/c++在 C/C++ 中非阻塞写入文件
【发布时间】:2010-12-13 22:45:08
【问题描述】:

我正在编写一个日志程序,我需要每秒从串行读取一次,然后打印到日志文件。 问题是有时,有些东西阻碍了我的循环并且数据正在备份。在对循环中的每个活动进行计时后,我注意到将我的数据打印到日志文件的函数有时会占用太多时间。我正在研究非阻塞写入文件,并根据这篇文章:

File writing with overlapped IO vs file writing in a separate thread

默认情况下,“写入文件”不应阻止我的程序。但似乎他们是。

我正在使用 MS Visual Studio EX,并且正在编写一个 consol c++ 应用程序。有人可以告诉我fprintf<< 默认情况下是否应该是非阻塞/异步的?如果没有,有没有办法让它们变成这样?

【问题讨论】:

    标签: c++ c


    【解决方案1】:

    这是在 Linux 中的工作方式:

    由于内核缓冲,不能阻止对常规文件的写入/读取。但是,当内核用完用于缓冲的内存时,它们会阻塞。

    来自Linux 编程接口:Linux 和 UNIX 系统编程手册

    非阻塞模式可用于设备(​​例如,终端和 伪终端)、管道、FIFO 和套接字。 (因为文件描述符 对于管道和套接字不是使用 open() 获得的,我们必须启用 这个标志使用 fcntl() F_SETFL 操作在章节中描述 5.3.)

    O_NONBLOCK 通常对于常规文件被忽略,因为内核缓冲区缓存确保常规文件上的 I/O 不会阻塞, 如第 13.1 节所述。但是,O_NONBLOCK 确实有效果 对于使用强制文件锁定时的常规文件(第 55.4)。

    来自UNIX 环境中的高级编程第二版

    我们也说过不考虑与磁盘 I/O 相关的系统调用 慢,即使磁盘文件的读取或写入可能会阻塞 临时来电者。

    来自http://www.remlab.net/op/nonblock.shtml

    常规文件总是可读的,它们也总是可写的。 这在相关的 POSIX 规范中有明确说明。我不能 强调这一点。将常规文件置于非阻塞状态 除了更改文件标志中的一位之外,绝对没有任何影响。

    从常规文件读取可能需要很长时间。例如,如果它位于繁忙的磁盘上,I/O 调度程序可能会占用很多时间 用户注意到应用程序被冻结的时间。

    尽管如此,非阻塞模式将不起作用。它根本行不通。检查文件的可读性或可写性总是成功 立即地。如果系统需要时间来执行 I/O 操作,它 将从读取或写入中将任务置于不可中断的睡眠状态 系统调用。

    【讨论】:

    • "'Regular' 对常规文件的写入/读取不能设为非阻塞。" - 这在语义上是正确的,但实际上是不正确的(假设来自您的 TLPI引用双重否定是无意的)。虽然您不能使系统调用成为非阻塞的,但实际上它永远不会阻塞,除非在非常不健康的情况下。写入只是缓冲区缓存的副本,pdflush 最终会自行决定将其写入磁盘。除非机器的物理 RAM 用完,否则不会发生阻塞之类的事情。但是,当这种情况发生时,无论如何,您都会因偶然的页面错误而被阻止。
    • 您的评论真的很有帮助。谢啦!我已经编辑了你提到的双重否定。希望它是固定的。
    【解决方案2】:

    IO 流通常是缓冲的,并且这些缓冲区经常被刷新(到操作系统,然后到磁盘),但是您几乎无法控制何时以及以何种频率(严格来说可以,但是您不希望到...)当冲洗发生时,您会看到异常值。

    “非阻塞”和“异步”不是我会在标准流中使用的词。如果您想减少这些延迟,请考虑内存映射文件写入 - boost 为内存映射文件提供了一个很好的便携式包装器。

    【讨论】:

      【解决方案3】:

      fprintf 和

      【讨论】:

        【解决方案4】:

        根据您的描述,您似乎写的数据太少了太多次。 如果 IO 活动很高,则可能会导致缓冲文件 I/O 延迟。如前所述,您可以使用基于内存的文件或使用块写入。 这个想法是通过一次合并多个写入来减少写入次数,因此不是每次写入 10 次 500 字节,而是每次写入 5k。 在大多数操作系统中,典型的页面大小(和写入大小)约为 4k(不确定 Windows)。 所以尝试一些开源包或编写一个可以减少写入次数的包装器。

        【讨论】:

          猜你喜欢
          • 2016-11-17
          • 1970-01-01
          • 2011-03-10
          • 1970-01-01
          • 1970-01-01
          • 2013-05-24
          • 2010-10-01
          • 1970-01-01
          相关资源
          最近更新 更多