I am implementing a multithreaded program that uses different cores, and many threads are executed simultaneously. Each thread makes a printf()
call, and the result is not readable.
How can I make printf()
atomic, so that a printf()
call in one thread doesn't conflict with a printf()
call in another?
For linux ,here's the code for u in c:3 threads ,executing on different cores printing hello world ,not conflicting with each other courtisey of lock .
POSIX Specifications
The POSIX specification includes these functions:
getc_unlocked()
getchar_unlocked()
putc_unlocked()
putchar_unlock()
The specification for these functions mention:
flockfile()
ftrylockfile()
funlockfile()
The specification for
flockfile()
et al includes the blanket requirement:This supersedes the suggested code in previous editions of this answer. The POSIX standard also specifies:
There are also the specifications for the character I/O functions:
getc()
getchar()
putc()
putchar()
fgetc()
fputc()
The formatted output functions are documented here:
printf()
One key provision in the
printf()
specification is:Note the use of 'as if'. However, each of the
printf()
functions is required to apply the lock so that access to a stream is controlled in a multi-threaded application. Only one thread at a time can be using a given file stream. If the operations are user-level calls tofputc()
, then other threads can intersperse the output. If the operations are user-level calls such asprintf()
, then the whole call and all access to the file stream is effectively protected so that only one thread is using it until the call toprintf()
returns.In the section of the System Interfaces: General Information section of POSIX on the subject of Threads, it says:
The list of exempted functions does not contain
fputc
orputc
orputchar
(orprintf()
et al).Interpretation
Rewritten 2017-07-26.
printf()
conceptually callflockfile()
at the start anfunlockfile()
at the end, which means that the POSIX-defined stream output functions are also thread-safe per call.flockfile()
andfunlockfile()
on the relevant stream (without interfering with the system's use of the*lockfile()
functions.This means there is no need to create mutexes or equivalent mechanisms for yourself; the implementation provides the functions to allow you to control the access to
printf()
et al in a multi-threaded application.…Code from previous answer removed as no longer relevant…
In order not to mix the outputs from different threads, you need to make sure that only one thread uses
printf
at a time. To achieve this, the simplest solution is to use amutex
. At the beginning initialize themutex
:Then make a wrapper around
printf
to make sure that only the thread that got themutex
can callprintf
(otherwise it will have to block until themutex
is available) :