14

A simple question:

I need to add some logging to my program.

If two processes use "fwrite" on the same file but not the same file descriptor will the written log messages be atomic or mixed. Is there a length limit?

Is it defined ANSI-C behaviour or implementation defined? If the later what is on MacOSX, Linux and Windows MSVC?

Lothar
  • 12,537
  • 6
  • 72
  • 121
  • From experience, higher priority tasks / thread will place their text somewhere in the text of a lower priority thread. This can be resolved by having one task output from a queue and another task append to the queue. – Thomas Matthews Feb 08 '10 at 23:08

4 Answers4

19

After doing some research and I've found the following in this link:

POSIX standard requires that C stdio FILE* operations are atomic. POSIX-conforming C libraries (e.g, on Solaris and GNU/Linux) have an internal mutex to serialize operations on FILE*s.

It looks like that calls should be atomic, but it depends on your platform. In same link, there is also another paragraph that lets you think that the programmer should take care:

So, for 3.0, the question of "is multithreading safe for I/O" must be answered with, "is your platform's C library threadsafe for I/O?" Some are by default, some are not; many offer multiple implementations of the C library with varying tradeoffs of threadsafety and efficiency. You, the programmer, are always required to take care with multiple threads.

Also, as you have two different FILE* in two different processes, I think you have no choice.

yeyeyerman
  • 7,751
  • 7
  • 43
  • 52
  • 1
    But each process has its own FILE? – Will Feb 08 '10 at 09:33
  • 2
    Also on Windows, `fwrite` is atomic. [source](https://msdn.microsoft.com/en-us/library/h9t88zwz.aspx?f=255&MSPPError=-2147217396): *Because this function locks the calling thread, it is thread-safe. For a non-locking version, see _fwrite_nolock.* – rustyx Aug 17 '16 at 10:38
5

It can be mixed.

If you have more than one thread/process writing to the same file, you need to use locking.

An alternative is to send log messages to a dedicated service/thread. An excellent tool to adopt is syslog, which is surely installed on all unixes and can be run on Windows.

Will
  • 73,905
  • 40
  • 169
  • 246
  • My understanding is that in general scenario: general advice is that you must lock file manually, but *under specific OP's scenario of logging into file* - **there's no need to lock file**. Each line you send to fwrite(line) will NOT be broken up or mangled. But sequential calls to fwrite() from process1 may not result in sequential lines in the log file (if process2 is also writing lines in parallel). So if you're only "dropping lines" into file, seems like using fwrite() is safe. If you're modifying multiple locations in the file (eg. data and index) then you absolutely need to use locking. – Dimitry K Dec 25 '20 at 19:37
  • Seems that behaviour I described is only guaranteed when file opened for writing in APPEND mode. See https://stackoverflow.com/a/35258623/1168382 – Dimitry K Dec 25 '20 at 19:43
2

From "man flockfile" on Debian lenny, the stdio functions are thread-safe.

There're thread-unsafe stdio functions, "man unlocked_stdio" for more details.

You can get more information from the man page.

cyfdecyf
  • 816
  • 2
  • 10
  • 20
-1

fwrite for visual studio locks the calling thread and is therefore thread-safe

Lefteris E
  • 2,806
  • 1
  • 24
  • 23