Online Book Reader

Home Category

Professional C__ - Marc Gregoire [396]

By Root 1112 0
is initialized exactly once as an alternative to using call_once(). The following example shows how you can implement this. It is called the double-checked locking algorithm because it is checking the value of the initialized variable twice, once before acquiring the lock and once right after acquiring the lock. The first initialized check is to prevent obtaining a lock when it is not needed and will increase performance. The second check is required to make sure that no other thread performed the initialization between the first initialized check and acquiring the lock:

class MyClass

{

public:

void init() {cout << "Init" << endl;}

};

MyClass var;

bool initialized = false;

mutex mut;

void func()

{

if (!initialized) {

unique_lock lock(mut);

if (!initialized) {

var.init();

initialized = true;

}

}

cout << "OK" << endl;

}

int main()

{

cout.sync_with_stdio(true); // Make sure cout is thread-safe

vector threads;

for (int i = 0; i < 5; ++i)

threads.push_back(thread{func});

for (auto& t : threads)

t.join();

return 0;

}

Code snippet from mutex\double_checked_locking.cpp

The output of this program is as follows:

Init

OK

OK

OK

OK

OK

This output clearly shows that only one thread has initialized the MyClass instance.

CONDITION VARIABLES


Condition variables allow a thread to block until a certain condition is set by another thread or until the system time reaches a specified time. They allow for explicit inter-thread communication. If you are familiar with multithreaded programming using the Win32 API, you can compare condition variables with event objects in Windows.

You need to include the header file to use condition variables. There are two kinds of condition variables available in the standard:

std::condition_variable: A condition variable that can only wait on a unique_lock, which, according to the standard, allows for maximum efficiency on certain platforms.

std::condition_variable_any: A condition variable that can wait on any kind of object, including custom lock types.

The condition_variable class supports the following methods:

notify_one();

Wake up one of the threads waiting on this condition variable. This is similar to an auto-reset event in Windows.

notify_all();

Wake up all threads waiting on this condition variable.

wait(unique_lock& lk);

The thread calling wait() should already have acquired a lock on lk. The effect of calling wait() is that it will atomically call lk.unlock() and then block the thread, waiting for a notification. When the thread is unblocked by a notify_one() or notify_all() call in another thread, the function will call lk.lock() again, possibly blocking on the lock and then returns.

wait_for(unique_lock& lk,

const chrono::duration& rel_time);

Similar to the previous wait() method, except that the thread will be unblocked by a notify_one() call, a notify_all() call, or when the given timeout has expired.

wait_until(unique_lock& lk,

const chrono::time_point& abs_time);

Similar to the previous wait() method, except that the thread will be unblocked by a notify_one() call, a notify_all() call, or when the system time passes the given absolute time.

There are also versions of wait(), wait_for(), and wait_until() that accept an extra predicate parameter. For example, wait() accepting an extra predicate is equivalent to:

while (!predicate())

wait(lk);

The condition_variable_any class supports the same methods as the condition_variable class except that it accepts any kind of Lock class instead of only a unique_lock.

Condition variables can, for example, be used for background threads processing items from a queue. You can define a queue in which you insert items to be processed. A background thread waits until there are items in the queue. When an item is inserted into the queue, the thread wakes up, processes the item, and goes back to sleep, waiting for the next item. Suppose you have the following queue:

std::queue mQueue;

Return Main Page Previous Page Next Page

®Online Book Reader