It seems that glibc's implementation of fprintf() is thread-safe, but is that so for Microsoft's CRT, as well?
By thread-safe, I don't mean just crashing, but also that if multiple threads (in the same process) call fprintf()
, the texts will not be mixed.
That is, for example, if thread A calls fprintf(stdout, "aaaa");
and thread B calls fprintf(stdout, "bbbb");
it's guaranteed not to mix to become aabbaabb
.
Is there such a guarantee?
Emscripten's implementation of fprintf isn't thread-safe in the sense that lines printed from different threads may interleave with each other, producing merged/corrupted messages in the result.
qDebug() is thread-safe. That means your program won't get corrupted or crash if you use qDebug() in multiple threads. However, qDebug() sends data to stderr which is unbuffered.
Thread safe: Implementation is guaranteed to be free of race conditions when accessed by multiple threads simultaneously. Conditionally safe: Different threads can access different objects simultaneously, and access to shared data is protected from race conditions.
Yes. In the multithreaded runtime libraries, every stream has an associated lock. This lock is acquired at the beginning of any call to a printf function and not released until just before that printf function returns.
This behavior is required by C11 (there was no concept of "threads" in standard C until C11). C11 §7.21.2/7-8 states:
Each stream has an associated lock that is used to prevent data races when multiple threads of execution access a stream, and to restrict the interleaving of stream operations performed by multiple threads. Only one thread may hold this lock at a time. The lock is reentrant: a single thread may hold the lock multiple times at a given time.
All functions that read, write, position, or query the position of a stream lock the stream before accessing it. They release the lock associated with the stream when the access is complete.
Visual C++ does not fully support C11, but it does conform to this requirement. A couple of other Visual C++-specific comments:
As long as you are not defining _CRT_DISABLE_PERFCRIT_LOCKS
(which only works with the statically-linked runtime libraries, libcmt.lib and friends) or using the _nolock-suffixed functions, then most operations on a single stream are atomic.
If you require atomicity across multiple operations on a stream, you can acquire the lock for a file yourself by acquiring and releasing the stream lock yourself using _lock_file
and _unlock_file
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With