Home > other >  C condition variable wait, does the wait block if the predicate is already true?
C condition variable wait, does the wait block if the predicate is already true?

Time:01-27

Here I am the Writer worker thread, I want to know if the main Reader thread has reached the PrepDone state.

  mylock.lock();
  m_writer_cv.wait (mylock, [this]
      {
          return this->m_reader_state == ReaderState::PrepDone;
      }
  );
  m_writer_state = WriterState::BlockWriteDone;
  mylock.unlock();
  m_reader_cv.notify_one();

And below I am the reader, there I want to know if if Writer reached WriteDone.

              mylock.lock();
              m_reader_state = ReaderState::PrepDone;
              m_reader_cv.wait(mylock, [this]
                    {
                        return this->m_writer_state == WriterState::BlockWriteDone;
                    }
              );
              mylock.unlock();
              m_writer_cv.notify_one();

Obvious, a hung like situation is observed, its like each is waiting for the other, and neither calling the respective notify_one(). Appreciate any feedback thanks.

CodePudding user response:

TLDR: It won't wait.

This:

  mylock.lock();
  m_writer_cv.wait (mylock, [this]
      {
          return this->m_reader_state == ReaderState::PrepDone;
      }
  );

Is equivalent to this:

  mylock.lock();
  while !(this->m_reader_state == ReaderState::PrepDone) {
      m_writer_cv.wait(mylock);
  };

To avoid your race condition, change this:

          mylock.lock();
          m_reader_state = ReaderState::PrepDone;

To do an initial notify the moment the initial m_reader_state variable is set.

          mylock.lock();
          m_reader_state = ReaderState::PrepDone;
          m_writer_cv.notify_one(); // signal the other thread

CodePudding user response:

A condition variable wait function that takes a predicate will only block while the predicate is false. It will never wait when the predicate is true. Because you call wait holding the associated lock, a race condition is not possible. This is the entire point of condition variables.

  • Related