Sun Studio 12: C++ User's Guide

11.4.1.4 Reducing Performance Overhead of MT-Safe Classes

Using the MT-safe classes in this version of the libC library results in some amount of performance overhead, even in a single-threaded application; however, if you use the unsafe_ classes of libC, this overhead can be avoided.

The scope resolution operator can be used to execute member functions of the base unsafe_ classes; for example:


    cout.unsafe_ostream::put(’4’);

    cin.unsafe_istream::read(buf, len);

Note –

The unsafe_ classes cannot be safely used in multithreaded applications.


Instead of using unsafe_ classes, you can make the cout and cin objects unsafe and then use the normal operations. A slight performance deterioration results. The following example shows how to use unsafe cout and cin:


Example 11–4 Disabling MT-Safety


#include <iostream.h>
//disable mt-safety
cout.set_safe_flag(stream_MT::unsafe_object);    
//disable mt-safety
cin.set_safe_flag(stream_MT::unsafe_object);    
cout.put(”4’);
cin.read(buf, len);

When an iostream object is MT-safe, mutex locking is provided to protect the object’s member variables. This locking adds unnecessary overhead to an application that only executes in a single-threaded environment. To improve performance, you can dynamically switch an iostream object to and from MT-safety. The following example makes an iostream object MT-unsafe:


Example 11–5 Switching to MT-Unsafe


fs.set_safe_flag(stream_MT::unsafe_object);// disable MT-safety
    .... do various i/o operations

You can safely use an MT-unsafe stream in code where an iostream is not shared by threads; for example, in a program that has only one thread, or in a program where each iostream is private to a thread.

If you explicitly insert synchronization into the program, you can also safely use MT-unsafe iostreams in an environment where an iostream is shared by threads. The following example illustrates the technique:


Example 11–6 Using Synchronization With MT-Unsafe Objects


    generic_lock();
    fs.set_safe_flag(stream_MT::unsafe_object);
    ... do various i/o operations
    generic_unlock();

where the generic_lock and generic_unlock functions can be any synchronization mechanism that uses such primitives as mutex, semaphores, or reader/writer locks.


Note –

The stream_locker class provided by the libC library is the preferred mechanism for this purpose.


See 11.4.5 Object Locks for more information.