0

I refer to the accepted answer here: Using std::conditional_variable to wait on a condition and in particular the code (copied):

struct gate {
  bool gate_open = false;
  mutable std::condition_variable cv;
  mutable std::mutex m;

  void open_gate() {
    std::unique_lock<std::mutex> lock(m);
    gate_open=true;
    cv.notify_all();
  }
  void wait_at_gate() const {
    std::unique_lock<std::mutex> lock(m);
    cv.wait( lock, [this]{ return gate_open; } );
  }
};

I don't understand how this works as an event class. How exactly does the code inside the mutex in open_gate execute if something is already waiting via the wait_at_gate functions. I'm guessing it has something to do with the std::condition_variable.

Jibbity jobby
  • 1,255
  • 2
  • 12
  • 26
  • 2
    The condition variable unlocks its acquired lock and waits to be signaled, hence `open_gate` may proceed. – Passer By Nov 22 '17 at 16:54
  • OK, so when the cv unlocks it remains blocked un til the other thread sets the gate_open and then calls the notify_all. This then calls the cv.wait handler, which if true (which it will be), unblocks the cv.wait? This all correct? – Jibbity jobby Nov 22 '17 at 16:59
  • 2
    Saying the same as @PasserBy, but in a little more detail: the `cv.wait(lock,...)` call _unlocks_ the mutex, and then it waits to be notified, and then it re-locks the mutex before it returns. – Solomon Slow Nov 22 '17 at 17:00
  • I'll accept an answer that has a detailed sequence of operations in cluding the gate_open and notify_all. – Jibbity jobby Nov 22 '17 at 17:02
  • 1
    Detailed sequence described: http://en.cppreference.com/w/cpp/thread/condition_variable. Tutorial on posix condition variables: https://computing.llnl.gov/tutorials/pthreads/#ConditionVariables. – rici Nov 22 '17 at 19:08

1 Answers1

0

OK, since no one is going to post, here's my answer, helped by the comments and the following links (from which quoted text is from, which slight modification for readability):

http://en.cppreference.com/w/cpp/thread/condition_variable, http://en.cppreference.com/w/cpp/thread/condition_variable/wait, http://en.cppreference.com/w/cpp/thread/condition_variable/notify_all

It assumes two threads, one, named OG, calling open_gate() and the other, named WG, calling wait_at_gate().

1) Both functions are protected with locks, it is a requirement that "any thread that intends to wait on std::condition_variable" acquires "a std::unique_lock<std::mutex>, on the same mutex as used to protect the shared variable".

2) If OG gets the lock first then it will open the gate before releasing the lock. WG then gets its lock, the gate is already opened. For this case since (from linked references):

while (!pred()) {
    wait(lock);
} 

then there is no wait.

3) If WG gets its lock first then its call to cv.wait "atomically releases the mutex and suspends the execution of the thread."

4) This allows OG to proceed, which then sets the shared flag. WG "will then be unblocked when notify_all() is executed" by OG.

Jibbity jobby
  • 1,255
  • 2
  • 12
  • 26