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?
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
.
来源:https://stackoverflow.com/questions/22539282/is-msvcrts-implementation-of-fprintf-thread-safe