Is glibc's implementation of fprintf() thread-

2019-02-09 16:36发布

问题:

Is fprintf thread-safe? The glibc manual seems to say it is, but my application, which writes to a file using single call to fprintf() seems to be intermingling partial writes from different processes.

edit: To clarify, the program in question is a lighttpd plugin, and the server is running with multiple worker threads.

Looking at the file, some of the writes are intermingled.

edit 2: It seems the problem I'm seeing might be due to lighttpd's "worker threads" actually being separate processes: http://redmine.lighttpd.net/wiki/lighttpd/Docs:MultiProcessor

Problems

By running 2 or more processes on the same socket you will have a better concurrency, but will have a few drawbacks that you have to be aware of:

  • mod_accesslog might create broken access logs, as the same file is opened twice and is NOT synchronized.
  • mod_status will have n separate counters, one set for each process.
  • mod_rrdtool will fail as it receives the same timestamp twice.
  • mod_uploadprogress will not show correct status.

回答1:

You're confusing two concepts - writing from multiple threads and writing from multiple processes.

Inside a process its possible to ensure that one invocation of fprintf is completed before the next is allowed access to the output buffer, but once your app pumps that output to a file you're at the mercy of the OS. Without some kind of OS based locking mechanism you cant ensure that an entirely different application doesnt write to your log file.



回答2:

Sounds to me like you need to read on file locking. The problem you have is that multiple processes (i.e. not threads) are writing to the same file simultaneously and there is no reliable way to insure the writes will be atomic. This can result in files overwriting each other's writes, mixed output, and altogether non-deterministic behaviour.

This has nothing to do with Thread Safety, as this is relevant only in single-process multithreading programs.



回答3:

The current C++ standard says nothing useful about concurrency, nor does the 1990 C standard. (I haven't read the 1999 C standard, so can't comment on it; the upcoming C++0x standard does say things, but I don't know exactly what offhand.)

This means that fprintf() itself is likely neither thread-safe nor otherwise, and that it would depend on the implementation. I'd read exactly what the glibc documentation says about it, and compare it to exactly what you're doing.