RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Simpler Multithreading in C++0x : Page 3

The new standard will support multithreading, with a new thread library. Find out how this will improve porting code, and reduce the number of APIs and syntaxes you use.

Protecting Data During Initialization
If your data only needs protecting during its initialization, using a mutex is not the answer. Doing so only leads to unnecessary synchronization after initialization is complete. The C++0x standard provides several ways of dealing with this.

First, suppose your constructor is declared with the new constexpr keyword and satisfies the requirements for constant initialization. In this case, an object of static storage duration, initialized with that constructor, is guaranteed to be initialized before any code is run as part of the static initialization phase. This is the option chosen for std::mutex, because it eliminates the possibility of race conditions with initialization of mutexes at a global scope:

class my_class
        int i;

        constexpr my_class():i(0){}

        my_class(int i_):i(i_){}

        void do_stuff();

    my_class x; // static initialization with constexpr constructor

    int foo();
    my_class y(42+foo()); // dynamic initialization

    void f()
        y.do_stuff(); // is y initialized?
Your second option is to use a static variable at block scope. In C++0x, initialization of block scope static variables happens the first time the function is called. If a second thread should call the function before the initialization is complete, then that second thread has to wait:

    void bar()
        static my_class z(42+foo()); // initialization is thread-safe

If neither options apply (perhaps because the object is dynamically allocated), then it's best to use std::call_once and std::once_flag. As the name suggests, when std::call_once is used in conjunction with a specific instance of type std::once_flag, the specified function is called exactly once:

    my_class* p=0;
    std::once_flag p_flag;

    void create_instance()
        p=new my_class(42+foo());

    void baz()
Just as with the std::thread constructor, std::call_once can take function objects instead of functions, and can pass arguments to the function. Again, copying is the default, and you have to use std::ref if you want a reference.

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date