Say I have two threads that print something (relatively long) either to stderr
or stdout
, is the function to both these streams thread-safe in the sense that they will never "interleave" characters? So, for example, if I have "Hello, World", I will never get "HHellllo,, WorldWorld" Or whatever other interleaving? This is for x86, GCC, Linux > 3.0.

- 19,515
- 28
- 127
- 217
-
possible duplicate of [Is it thread safe to call printf in threads that run simultaneously?](http://stackoverflow.com/questions/4353651/is-it-thread-safe-to-call-printf-in-threads-that-run-simultaneously) – Jens Gustedt Oct 20 '12 at 13:39
-
@JensGustedt: I saw that, but it doesn't answer whether *both* `stderr` and `stdout` are thread-safe. Somewhere I read that this is not the case with `stderr`, and I need to make sure. – Dervin Thunk Oct 20 '12 at 13:43
-
possible duplicate of [stdout thread-safe in C on Linux?](http://stackoverflow.com/questions/467938/stdout-thread-safe-in-c-on-linux) – Kate Gregory Oct 20 '12 at 14:09
-
2@DervinThunk using a written-language only form of communication has its challenges. Years ago I learned if people didn't get my meaning from what I wrote, I needed to write more clearly, not tell them off for misreading. If you want everyone to know that your question is special and different, make that clear. You'll get better answers, too. A simple "I know **xyz**, I've read [link to other question], and I'm asking **abc**" usually does the trick. – Kate Gregory Oct 21 '12 at 01:58
2 Answers
I took a look at glibc, and each call to vfprintf
will call the POSIX flockfile
(_IO_flockfile
) and funlockfile
(_IO_funlockfile
) on the stream.
So, the characters within a call won't get interleaved with characters from a call from another thread as only one thread can hold the lock on stdout
or stderr
.
All bets are off as to the ordering of multiple calls across the various threads though.

- 8,267
- 1
- 22
- 18
-
Ok, this is the answer I was expecting. And I agree that ordering is off across various threads. Anyone has problems with this answer? – Dervin Thunk Oct 20 '12 at 14:40
-
2Also, C2011 has thread support and it says equivalent things about locking on a single I/O channel across threads for a single call. However, the standards say nothing about what happens if one thread writes on stdout while another writes on stderr; those outputs could be interleaved on the screen because of concurrent execution. – Jonathan Leffler Oct 20 '12 at 14:48
-
@JonathanLeffler Re: "what happens if one thread writes on stdout while another writes on stderr": is it possible to somehow route `stdout` to screen 1 and `stderr` to screen 2? – pmor Apr 23 '22 at 17:20
No. Even in a single-threaded program you can get interleaving because of different buffering rules. By default, stdout is line-buffered while stderr is unbuffered. You can make them both unbuffered via:
setvbuf(stdout, NULL, _IONBF, 0)
See also stdout thread-safe in C on Linux?, particularly R.'s answer. And also Jonathan Leffler's comment.
Edit: By default, stdout will be fflush
'd at the end of each line or when the buffer is full. The latter could occur in the middle of a line. Then, if stdout and stderr both have the same underlying file descriptor, the output fprintf(stderr,... could be inserted into the middle of a line.
But it can be worse. Often you wish to redirect both stderr and stdout to a file or pipe. The man page for setbuf(3)
on my system notes:
If a stream refers to a terminal (as stdout normally does) it is line buffered. The standard error stream stderr is always unbuffered by default.
So in this case, stdout becomes block-buffered, and in practice it seems that almost every output to stderr is interleaved with that of stdout. This can be alleviated by addding:
setlinebuf(stdout);
Or by making stdout unbuffered.

- 1
- 1

- 9,553
- 10
- 54
- 77
-
1What interleaving will you get in a single-threaded code? one `printf` will finish writing before anotther `printf` starts. I don't understand what you're saying, sorry. – Dervin Thunk Oct 20 '12 at 14:03
-
3By default, stdout will be `fflush`d at the end of each line ***or*** when the buffer is full. The latter could occur in the middle of a line. Then, if stdout and stderr both have the same underlying file descriptor, the output `fprintf(stderr,...` could be inserted into the middle of a line. – Joseph Quinsey Oct 20 '12 at 14:56
-
See also Jonathan Leffler's comment to http://stackoverflow.com/a/12989477/318716. – Joseph Quinsey Oct 20 '12 at 15:15