我正在写一个日志程序,我需要每秒读取一次串行然后打印到日志文件.问题是,有时候某些东西会阻碍我的循环并且数据会被备份.在对循环中的每个活动进行计时之后,我注意到将数据打印到日志文件的函数有时会花费太多时间.我正在研究非阻塞写入文件,并根据这篇文章:
默认情况下,"写入文件"不应该阻止我的程序.但它似乎是.
我正在使用MS visual studio EX,我正在编写一个consol c ++应用程序.谁能告诉我,如果fprintf和<<被认为是非阻塞/默认异步?如果没有,有没有办法让它们如此?
以下是Linux中的工作原理:
由于内核缓冲,不能阻止对常规文件的写入/读取.但是,当内核耗尽内存进行缓冲时,它们会阻塞.
来自Linux编程接口:Linux和UNIX系统编程手册:
非阻塞模式可以与设备(例如,终端和伪终端),管道,FIFO和套接字一起使用.(因为管道和套接字的文件描述符不是使用open()获得的,所以我们必须使用第5.3节中描述的fcntl()F_SETFL操作来启用此标志.)
对于常规文件,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操作,它将使任务处于读取或写入系统调用的不可中断睡眠状态.
IO流通常是缓冲的,并且每隔一段时间这些缓冲区就会被刷新(到操作系统,然后到磁盘),但是你几乎无法控制何时以及以什么频率(严格来说你可以,但是你不想...... .) 当潮水发生时,您就会看到异常值。
“非阻塞”和“异步”不是我在标准流中使用的词。如果您想减少这些延迟,请考虑内存映射文件写入 - boost 对于内存映射文件有一个很好的便携式包装器。