Ensuring thread safety (C++)
If you are building multithreaded C++ applications, there are some thread-safety issues which you need to consider when using objects defined in the C++ Standard Template Library or in the stream classes.
Ensuring thread safety of template objects
- algorithm
- deque
- functional
- iterator
- list
- map
- memory
- numeric
- queue
- set
- stack
- utility
- valarray
- vector
ILE C++ supports reentrancy to the extent that you can safely read a single object from multiple threads simultaneously. This level of reentrancy is intrinsic. No locks or other globally allocated resources are used.
- A single container object is written by multiple threads simultaneously.
- A single container object is written in one thread, while being read in one or more other threads.
If multiple threads write to a single container, or a single thread writes to a single container while other threads are reading from that container, it is your responsibility to serialize access to this container. If multiple threads read from a single container, and no processes write to the container, no serialization is necessary.
Ensuring thread safety of string objects
The classes declared in the string standard library are not thread-safe by default and thus may not work correctly in a multithreaded application.
If thread-safety is desired, the following macro variable should be defined prior to the inclusion of the string header.
__MULTI__
The macro can be defined within the source code or with a DEFINE('__MULTI__') parameter on the CRTCPPMOD or CRTBNDCPP command.
When an application is built with this macro defined, standard library routines used with string objects are thread safe.
Ensuring thread safety of stream objects
All classes declared in the iostream standard library are reentrant, and use a single lock to ensure thread-safety while preventing deadlock from occurring. However, on multiprocessor machines, there is a chance, although rare, that livelock can occur when two different threads attempt to concurrently access a shared stream object, or when a stream object holds a lock while waiting for input (for example, from the keyboard). If you want to avoid the possibility of livelock, you can disable locking in input stream objects, output stream objects, or both, by using the following macros at compile time:
- __NOLOCK_ON_INPUT
- Disables input locking.
- __NOLOCK_ON_OUTPUT
- Disables output locking.
To use one or both of these macros, specify the macro name with the DEFINE option on the compilation command line. For example:
CRTCPPMOD DEFINE('__NOLOCK_ON_INPUT') DEFINE('__NOLOCK_ON_OUTPUT')
However, if you disable locking on input or output objects, it is your responsibility to provide the appropriate locking mechanisms in your source code if stream objects are shared between threads. If you do not, the behavior is undefined, with the possibility of data corruption or application crash.