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.