C 终止时刷新文件输出的策略

C 终止时刷新文件输出的策略,c,windows,buffer,C,Windows,Buffer,我有一个监控高速通信链路并将日志写入文件(通过标准C文件IO)的应用程序。到达链接的消息的响应时间很重要,因此我故意不在每条消息处刷新文件,因为这会减慢我的响应时间 但是,在某些情况下,我的应用程序会被“暴力”终止(例如,通过终止进程),在这些情况下,最后几条日志消息不会被写入(即使通信链路已经安静了一段时间) 我可以使用什么技术/策略来确保我的大部分数据都被刷新,但又不放弃响应速度 编辑:应用程序在Windows上运行,使用线程是标准的解决方案。让数据收集代码将数据写入线程安全队列,并使用信号

我有一个监控高速通信链路并将日志写入文件(通过标准C文件IO)的应用程序。到达链接的消息的响应时间很重要,因此我故意不在每条消息处刷新文件,因为这会减慢我的响应时间

但是,在某些情况下,我的应用程序会被“暴力”终止(例如,通过终止进程),在这些情况下,最后几条日志消息不会被写入(即使通信链路已经安静了一段时间)

我可以使用什么技术/策略来确保我的大部分数据都被刷新,但又不放弃响应速度


编辑:应用程序在Windows上运行,使用线程是标准的解决方案。让数据收集代码将数据写入线程安全队列,并使用信号量向写入线程发送信号


但是,在开始之前,请仔细检查您的断言,即fflush()会很慢。大多数操作系统都有文件系统缓存。它使写入速度非常快,就像简单的内存到内存块复制一样。数据延迟写入磁盘,崩溃不会影响它。

如果您在Unix或Linux上,您的进程将收到一些您可以在信号处理程序中捕获的数据(除了
SIGKILL
)和
fflush()

有关信号捕捉,请参见
man SIGATION


编辑:不知道Windows。

如果程序通过调用exit()或从main()返回而终止,C标准保证打开的流被刷新和关闭,因此不需要特殊处理。从你的描述听起来,这就是正在发生的事情:如果你的程序由于一个信号而死亡,你将看不到刷新

我很难理解到底是什么问题

如果您只是想在频繁刷新和默认的完全缓冲输出之间找到一个令人满意的媒介,那么可能您需要的是行缓冲:

setvbuf(stream, 0, _IOLBF, 0);

不过我建议使用异步写入。这样,您不需要等待写入IOP的发生,操作系统也不会延迟IOP。请参见CreateFile()flags
文件_FLAG_WRITE_to |文件_FLAG_OVERLAPPED


您不需要
文件\u标志\u无缓冲
。这只是为了跳过操作系统缓存。只有当你担心整个操作系统都会死掉的时候,你才会需要它。

我不得不同意nobugz的观点-你确定fflush会让你慢下来吗?通常是sync()需要时间…不,您只担心I/O延迟。OP在退出时会看到缓冲日志消息,所以这是正常终止,而不是信号。还要注意的是,从信号处理程序调用fflush()是未定义的。在正常终止时,所有打开的FD都会被刷新和关闭,不是吗?OP改变了主意-问题的第一个版本说“最后几条日志消息现在已写入”而不是“未写入”——这有很大区别。写入与调用fflush()类似吗每次写入后?fflush的意思是“立即将其从缓存中取出,在完成之前不要再联系我”。这与异步写入完全不一致。对文件的异步写调用根本不会等待,不会等待操作系统缓存或实际磁盘。