Search code examples
c++multithreadingcondition-variable

How often false signals are triggered in a condition variable?


I don’t understand why std::condition_variable has more standard guarantees than this code:

class condition_variable {
public:
  void notify_one() {}
  void notify_all() {}
  void wait(unique_lock<mutex> &lock) {
    lock.unlock();
    this_thread::sleep_for(15ms);
    lock.lock();
  }
  void wait(unique_lock<mutex> &lock,
            const function<bool()> &pred) {
    while (!pred()) wait(lock);
  }
};

Solution

  • The simplest implementation for std::condition_variable::wait() would just correspond to busy waiting:

    template<typename Predicate>
    void wait(std::unique_lock<std::mutex>& lck, Predicate pred) {
       while (!pred()) {
          lck.unlock();
          lck.lock();
       }
    }
    

    For this reason, spurious wakeups can occur.

    Your implementation puts the thread to sleep between the release and the acquisition of the lock on the mutex:

    void wait(unique_lock<mutex> &lock) {
       lock.unlock();
       this_thread::sleep_for(15ms); // <--
       lock.lock();
    }
    

    Finding the right sleeping period may be difficult, though. The lower it is, the more it resembles busy waiting, and therefore the more CPU cycles are wasted. The higher it is, the fewer CPU cycles are wasted, but the worse is the responsiveness.

    How often spurious wakeups occur on your implementation depends on the election of the sleeping period.