Using boost condition variables

2019-07-04 15:56发布

问题:

I am designing an asynchronous logger class as follows. However, not sure if I am using the boost condition variable in the right way. Can anyone comment on this? Here the processLogEntry method is a thread function and I am using boost here.

void LogWriter::stopThread()
{
    mStop = true;
    mCond.notify_one();
    mThread->join();
}   

void LogWriter::processLogEntry()
{
    while(!mStop)
    {
        boost::mutex::scoped_lock lock(mMutex);
        mCond.wait(lock);
        while(!q.empty())
        {
            // process begins
        }
    }
}

void LogWriter::addLogEntry()
{
    boost::mutex::scoped_lock lock(mMutex);
    // add it in the queue
    mCond.notify_one();
}

回答1:

As it has been pointed out, you must either make mStop atomic or guard all its accesses with the mutex. Forget about volatile, it's not relevant to your purposes.

Furthermore, when waiting on a condition variable a call to wait may return even if no notification functions were called (those are so-called spurious wake-ups). As such, calls to wait need to be guarded.

void LogWriter::stopThread()
{
    {
        boost::mutex::scoped_lock lock(mMutex);
        mStop = true;
        mCond.notify_one();
    }
    mThread->join();

}   

void LogWriter::processLogEntry()
{
    for(;;) {
        boost::mutex::scoped_lock lock(mMutex);
        // We wait as long as we're not told to stop and
        // we don't have items to process
        while(!mStop && q.empty()) mCond.wait(lock);

        // Invariant: if we get here then
        // mStop || !q.empty() holds

        while(!q.empty())
        {
            // process begins
        }

        if(mStop) return;
    }
}


标签: c++ boost