|
|
C and C++ Libraries and Floating-Point Support Reference
C library functions that are not thread-safe
C library functions that are not thread-safeThe following table shows the C library functions that are
not thread-safe. Table 2. Functions that are not thread-safe | Functions | Description |
|---|
asctime(),
localtime(),
strtok()
| These functions are all
thread-unsafe. Each contains a static buffer that might be overwritten
by another thread between a call to the function and the subsequent
use of its return value. ARM supplies reentrant versions, _asctime_r(), _localtime_r(),
and _strtok_r(). ARM recommends that you use
these functions instead to ensure safety. NoteThese reentrant versions take additional parameters. _asctime_r() takes
an additional parameter that is a pointer to a buffer that the output
string is written into. _localtime_r() takes
an additional parameter that is a pointer to a struct tm,
that the result is written into. _strtok_r() takes
an additional parameter that is a pointer to a char pointer
to the next token. |
exit()
| Do not call exit() in
a multithreaded program even if you have provided an implementation
of the underlying _sys_exit() that actually
terminates all threads. In this case, exit() cleans
up before calling _sys_exit() so
disrupts other threads. | gamma(), []
lgamma(),
lgammaf(),
lgammal()
| These extended mathlib functions
use a global variable, _signgam, so are not thread-safe. | mbrlen(),
mbsrtowcs(),
mbrtowc(),
wcrtomb(),
wcsrtombs()
| The C89 multibyte conversion
functions (defined in stdlib.h) are not thread-safe, for
example mblen() and mbtowc(),
because they contain internal static state that is shared between
all threads without locking. However, the extended restartable
versions (defined in wchar.h) are thread-safe,
for example mbrtowc() and wcrtomb(),
provided you pass in a pointer to your own mbstate_t object.
You must exclusively use these functions with non-NULL mbstate_t
* parameters if you want to ensure thread-safety when
handling multibyte strings. |
rand(), srand()
| These functions keep internal
state that is both global and unprotected. This means that calls
to rand() are never thread-safe. ARM
recommends that you do one of the following: Use the reentrant versions _rand_r() and _srand_r() supplied
by ARM. These use user-provided buffers instead of static data within
the C library. Use your own locking to ensure that only one thread
ever calls rand() at a time, for example, by
defining $Sub$$rand() if you want to avoid
changing your code. Arrange that only one thread ever needs to generate
random numbers. Supply your own random number generator that can
have multiple independent instances.
Note_rand_r() and _srand_r() both
take an additional parameter that is a pointer to a buffer storing
the state of the random number generator.
| setlocale(), localeconv()
| setlocale() is
used for setting and reading locale settings. The locale settings
are global across all threads, and are not protected by a lock.
If two threads call setlocale() to simultaneously
modify the locale settings, or if one thread reads the settings
while another thread is modifying them, data corruption might occur.
Also, many other functions, for example strtod() and sprintf(),
read the current locale settings. Therefore, if one thread calls setlocale() concurrently
with another thread calling such a function, there might be unexpected
results.
Multiple threads reading the
settings simultaneously is thread-safe in simple cases and if no
other thread is simultaneously modifying those settings, but where internally
an intermediate buffer is required for more complicated returned
results, unexpected results can occur unless you use a reentrant
version of setlocale(). ARM recommends
that you either: Choose the locale
you want and call setlocale() once to initialize
it. Do this before creating any additional threads in your program
so that any number of threads can read the locale settings concurrently
without interfering with one another. Use the reentrant version _setlocale_r() supplied
by ARM. This returns a string that is either a pointer to a constant
string, or a pointer to a string stored in a user-supplied buffer
that can be used for thread-local storage, rather than using memory
within the C library.
Be
aware that _setlocale_r() is not fully thread-safe
when accessed concurrently to change locale
settings. This access is not lock-protected. Also, be
aware that localeconv() is not thread-safe.
Call the ARM function _get_lconv() with a pointer
to a user-supplied buffer instead. |
See also
|