This implementation of iostreams and locales provides Multithread-Safety Level 2 as an option. All public and protected functions are reentrant under certain conditions, and there is protection against multiple threads trying to modify static and global data. The library may also lock an iostream object before modifying it. When this level of multi-thread safety is enabled, client code is not required to explicitly lock or unlock a class object, whether static, global, or local, in order to perform a single operation on the object.
This means that iostream objects, with the exception of stream buffers, can be shared between threads of execution using a simple mutex object without explicit locking. The locking mechanism is enforced at the stream level. Therefore, all operations carried out on the stream are multithread safe, including the following:
Thread 1: | Thread 2: |
std::cout << "Thread 1" << std::endl; |
std::cout << " Thread 2" << std::endl; |
The eight standard iostream objects, std::cin, std::cout, std::cerr, std::clog, std::wcin, std::wcout, std::wcerr, and std::wclog, are normally thread-safe by default. Due to the overhead necessitated by thread-safety no other stream objects are thread-safe by default. This behavior can be customized when the library is configured.
Thread safety is controlled by two bits, ios_base::nolock and ios_base::nolockbuf. These bits can be set on an iostream object (such as std::cout) using the public member function std::ios_base::setf(). When the bits are set, the object behaves in a thread-safe way as described above. The public member function std::ios_base::unsetf() clears both bits. When the bits are not set, the object is not thread-safe. It is also possible to set the bits individually to allow the stream thread-unsafe access on the stream data (nolock), or to prevent the stream from locking prior to accessing the stream buffer (nolockbuf).
NOTE -- The C++ standard does not address multi-thread safety in any way. These bits are extensions to the standard. Code using these bits is inherently unportable.
The ios_base::nolock and ios_base::nolockbuf bits are not available in strictly conforming mode (strict ANSI).