2

I have an application that monitors a high-speed communication link and writes logs to a file (via standard C file IO). The response time to messages that arrive on the link is important, so I knowingly don't fflush the file at each message, because this slows down my response time.

However, in some circumstances my application is terminated "violently" (e.g. by killing the process), and in these cases the last few log messages are not written (even if the communication link has been quiet for some time).

What techniques/strategies can I use to make sure most of my data is flushed, but without giving up speed of response?

Edit: The application runs on Windows

4

4 回答 4

4

Using a thread is the standard solution to this. Have your data collection code write data to a thread-safe queue and use a semaphore to signal the writing thread.

However, before you go there, double-check your assertion that fflush() would be slow. Most operating systems have a file system cache. It makes writes very fast, as simple memory-to-memory block copy. The data gets written to disk lazily, your crash won't affect it.

于 2009-01-22T12:47:52.360 回答
3

If you are on Unix or Linux, your process would receive some termination signal which you can catch (except SIGKILL) and fflush() in your signal handler.

For signal catching see man sigaction.

EDIT: No idea about Windows.

于 2009-01-22T12:49:53.370 回答
2

我会建议异步写入。这样你就不需要等待写 IOP 发生,操作系统也不会延迟 IOP。请参阅 CreateFile() 标志FILE_FLAG_WRITE_THROUGH | FILE_FLAG_OVERLAPPED

你不需要FILE_FLAG_NO_BUFFERING。那只是为了跳过操作系统缓存。只有当您担心整个操作系统会剧烈死亡时,您才需要它。

于 2009-01-23T13:27:34.807 回答
-1

If your program terminates by calling exit() or returning from main(), the C standard guarantees that open streams are flushed and closed, so no special handling is needed. It sounds from your description like this is what is happening: if your program died due to a signal, you wouldn't see the flush.

I'm having trouble understanding what the problem is exactly.

If it's just that you're trying to find a happy medium between flushing often and the default fully buffered output, then maybe line buffering is what you want:

setvbuf(stream, 0, _IOLBF, 0);
于 2009-01-22T13:07:42.570 回答