How do I use a boost condition variable to wait for a thread to complete processing?

后端 未结 2 1718
我在风中等你
我在风中等你 2020-12-07 15:10

I am using a conditional variable to stop a thread until another thread has completed processing it\'s task queue (long story). So, on one thread I lock and wait:

         


        
2条回答
  •  暖寄归人
    2020-12-07 15:37

    Yes, you are misusing the condition variable. "Condition variables" are really just the signaling mechanism. You also need to be testing a condition. In your case what might be happening is that the thread that is calling notify_one() actually completes before the thread that calls wait() even starts. (Or at least, the notify_one() call is happening before the wait() call.) This is called a "missed wakeup."

    The solution is to actually have a variable which contains the condition you care about:

    bool worker_is_done=false;
    
    boost::mutex::scoped_lock lock(m_mutex);
    while (!worker_is_done) m_condition.wait(lock);
    

    and

    boost::mutex::scoped_lock lock(m_mutex);
    worker_is_done = true;
    m_condition.notify_one();
    

    If worker_is_done==true before the other thread even starts waiting then you'll just fall right through the while loop without ever calling wait().

    This pattern is so common that I'd almost go so far as to say that if you don't have a while loop wrapping your condition_variable.wait() then you always have a bug. In fact, when C++11 adopted something similar to the boost::condtion_variable they added a new kind of wait() that takes a predicate lambda expression (essentially it does the while loop for you):

    std::condition_variable cv;
    std::mutex m;
    bool worker_is_done=false;
    
    
    std::unique_lock lk(m);
    cv.wait(lk, []{return worker_is_done;});
    

提交回复
热议问题