Here is process a
and b
, both of which are multithreaded.
a
forks b
and b
immediatly execs one
If you're using a single FILE
object to perform output on an open file, then whole fprintf
calls on that FILE
will be atomic, i.e. lock is held on the FILE
for the duration of the fprintf
call. Since a FILE
is local to a single process's address space, this setup is only possible in multi-threaded applications; it does not apply to multi-process setups where several different processes are accessing separate FILE
objects referring to the same underlying open file. Even though you're using fprintf
here, each process has its own FILE
it can lock and unlock without the others seeing the changes, so writes can end up interleaved. There are several ways to prevent this from happening:
Allocate a synchronization object (e.g. a process-shared semaphore or mutex) in shared memory and make each process obtain the lock before writing to the file (so only one process can write at a time); OR
Use filesystem-level advisory locking, e.g. fcntl
locks or the (non-POSIX) BSD flock
interface; OR
Instead of writing directly to the log file, write to a pipe that another process will feed into the log file. Writes to a pipe are guaranteed (by POSIX) to be atomic as long as they are smaller than PIPE_BUF
bytes long. You cannot use fprintf
in this case (since it might perform multiple underlying write operations), but you could use snprintf
to a PIPE_BUF
-sized buffer followed by write
.