Boost.Thread, Condition Variables &Spurious wakeup

 boost::condition_variable is a utility to synchronize threads, and can be used as below:

boost::condition_variable cond;
boost::mutex mut;
bool data_ready;

void process_data();

void wait_for_data_to_process()
{
    boost::unique_lock<boost::mutex> lock(mut);
    while(!data_ready)
    {
        cond.wait(lock);
    }
    process_data();
}

This example is simple and intuitive except for one thing, according to this documentation,

 void wait(boost::unique_lock<boost::mutex>& lock)

Effects:


Atomically call lock.unlock() and blocks the current thread.

The thread will unblock when notified by a call to this->notify_one()

or this->notify_all(), or spuriously.

When the thread is unblocked (for whatever reason),

the lock is reacquired by invoking lock.lock() before the call to wait returns.

The lock is also reacquired by invoking lock.lock()

if the function exits with an exception.

Since  Wait() blocks the thread, why in the above example code snippet

while(!data_ready)

rather than

if(!data_ready)

is used?

This is because a spurious wakeup may cause cond.wait(lock) to return while data_ready remains unchanged(false).

This post gives a very detailed discussion about this issue.

Advertisements
Post a comment or leave a trackback: Trackback URL.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: