signal on condition variable without holding lock

前端 未结 2 2029
死守一世寂寞
死守一世寂寞 2021-01-05 04:06

So I just found out that it\'s legal to signal a condition variable if you\'re not holding the lock in c++11. That seems to open the door to some nasty race condition:

2条回答
  •  有刺的猬
    2021-01-05 04:49

    Checking the predicate and waiting are not performed atomically in std::condition_variable::wait (unlocking the lock and sleeping are performed atomically). If it is possible for another thread to change the value of the predicate while this thread holds the mutex, then it is possible for notifications to occur between the predicate check and going to sleep, and effectively be lost.

    In your example, if generate_data() in T2 can alter the result of is_empty() without holding m_mutex, it's possible for a notification to happen between T1 checking is_empty() and sleeping on m_cv. Holding the mutex at any time between the change to the predicate and the notification is sufficient to guarantee the atomicity of the predicate check and wait call in the other thread. That could look like:

    {
      std::lock_guard lk(m_mutex);
      generate_data();
    }
    m_cv.notify();
    

    or even

    generate_data();
    std::lock_guard(m_mutex); // Lock the mutex and drop it immediately
    m_cv.notify();
    

提交回复
热议问题