Are C standard library functions thread-safe in absence of C11 threads?

Viewed 733

I am writing a multi-threaded program on Windows. Since there is no windows implementation of C that I know of to support C11 threads, my best bet is to use the native WinAPI multi-threading. But there is a catch. Some functions in the C library, such as malloc or I/O functions are demanded to be thread-safe by the C11 standard. But are they required to be thread-safe even if __STDC_NO_THREADS__ is defined? It seems pointless for them to be thread-safe if no thread facilities exist in the C implementation, but it would truly help since I really don't want to have to wrap all I/O functions in mutexes.

4 Answers

No, standard library functions are not guaranteed to be thread-safe, regardless of thread library used. C11 7.1.4/4 explicitly states:

The functions in the standard library are not guaranteed to be reentrant and may modify objects with static or thread storage duration.

A particular standard library implementation or a library standard extension may provide thread-safe functions, on case by case basis.

Even in C11, guarantees of atomicity or thread safety within the Standard are only meaningful with regard to signals or threads that are created by Standard-defined means. If a thread is created via some means not specified by the Standard, anything that thread might do, including its possible interactions with other threads, would be outside the jurisdiction of the Standard.

Quality implementations intended for low-level programming on systems where it's possible to create threads or trigger asynchronous signals will generally allow programs to interact with such things in ways beyond those required by the Standard, since the Standard would provide for essentially nothing.

The most obvious and avoidable are those functions that use and often return a subroutine static data element, which of course is on the heap even though the name context is local. They are rare, but asctime() and some of its friends come to mind. https://linux.die.net/man/3/asctime The man page says obsolete, use strftime(). However, any function that exhibits 'state' probably has a static inside! For instance, strtok(): https://linux.die.net/man/3/strtok I never liked it, preferring to parse my strings by hand and not modify the input, using pointer derived lengths. So beware. A good C programmer could write most of these library routines, and so can imagine where subroutine static (or file static global or global) are used to give 'state'.

BTW, by strict definition, functions should have no state, but subroutines can! In C++, JAVA, etc. methods keep their state in their object or class, and for thread support can include a mutex at either or both levels, or you can make JAVA methods 'synchronized'!

Related