How should we deal with race condition for system's global variables like errno in UNIX? I looked at Tanenbaum's Modern Operating Systems(4th edition, page 117), and it says use private global variable. So basically you assign some chunk of memory for global variable, and pass it to each procedure as a parameter. But how does that solve the problem?
-
3Possible duplicate of [Is errno thread-safe?](https://stackoverflow.com/q/1694164/608639), [Is there a way to use errno safely in a multi-threaded application?](https://stackoverflow.com/q/449778/608639), etc. – jww Jun 16 '18 at 14:59
-
Okay. But what about the other static variables that are unique across the system or a process? – Mohmmed Jun 17 '18 at 05:03
2 Answers
As jww has linked, in most multithread aware standard libraries there are measures taken to ensure that the system global errno
is sane in a multithreaded environment. In this day and age, a library that doesn't sort this out would have to be considered "not helpful".
In the bad old days before multi-threaded libraries, calls to standard library functions that had side effects on things like errno
had to be guarded with semaphores. Yeurk.
In modern gccs, there's the extension __thread:
__thread long myThreadPrivateLong;
Other compilers probably have something similar. I have very occassionally found this useful in my own code.
Of course, other system globals like stdin
, stdout
, stderr
are not thread private. It makes no sense, as there is only one tty
for a process (alas*). On glibc, some measures are taken to ensure that multithreaded access to stdout
is semi-sane, in that functions like printf()
are buffered through pipes before actually being output to stdout
after glibc encounters an EOL. The result is that two threads calling printf()
at the same time will have their outputs line separated. In the old days, the characters output by the two calls to printf()
would simply be jumbled up into an un-readable mess. You still get this with simultaneous calls to fprintf(stderr,...)
because stderr
is not buffered.
*I say alas, because it would be really nice if there were thread-specific stdouts and the terminal application had a terminal tab per thread. Not very useful to users, but very useful to developers sometimes. It's useful to be able to see what an individual thread is doing.

- 7,580
- 15
- 22
Well, the best option is to just not use global variables. Write reentrant functions that make the user pass a variable of the right type (Most often in C it'll be a pointer to a variable) and use that. See, for example, strtok_r().
If it's a global variable you control because it's in user code and you can't avoid using it for some reason, there's thread local storage.
If it's a global in a library you use but can't alter, you'll have to make sure any uses of it is protected with a mutex.

- 47,241
- 3
- 26
- 60