Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why condition_variable is waiting for the lock in producer-consumer? C++

See the following classical producer-consumer code:

int main()
{
    std::queue<int> produced_nums;
    std::mutex m;
    std::condition_variable cond_var;
    bool done = false;
    bool notified = false;

    std::thread producer([&]() {
        for (int i = 0; i < 5; ++i) {
            std::this_thread::sleep_for(std::chrono::seconds(1));
            std::unique_lock<std::mutex> lock(m);
            std::cout << "producing " << i << '\n';
            produced_nums.push(i);
            notified = true;
            cond_var.notify_one();
        }

        done = true;
        cond_var.notify_one();
    });

    std::thread consumer([&]() {
        std::unique_lock<std::mutex> lock(m);
        while (!done) {
            while (!notified) {  // loop to avoid spurious wakeups
                cond_var.wait(lock);
            }
            while (!produced_nums.empty()) {
                std::cout << "consuming " << produced_nums.front() << '\n';
                produced_nums.pop();
            }
            notified = false;
        }
    });

    producer.join();
    consumer.join();
}

I have copied this from cppreference.

Everything is pretty much straightforward to me, except the line in the consumer:

cond_var.wait(lock); 

I do understand the loop that waits cond_var to be notified, but why is it waiting for the lock?

like image 342
Eduard Rostomyan Avatar asked May 21 '18 07:05

Eduard Rostomyan


People also ask

Does condition variable wait release lock?

std::condition_variable::wait 1) Atomically unlocks lock , blocks the current executing thread, and adds it to the list of threads waiting on *this. The thread will be unblocked when notify_all() or notify_one() is executed. It may also be unblocked spuriously.

How does the conditional variable prevent the threads from continuously waiting for the thread?

Answer. answer: a)The solution makes threads to check a condition and if that condition is true, then the threads go to sleep.

How does condition variable work C++?

Condition Variable is a kind of Event used for signaling between two or more threads. One or more thread can wait on it to get signaled, while an another thread can signal this. A mutex is required along with condition variable.


1 Answers

cond_var.wait(lock); does not wait for the lock. That line does 3 things

  1. It unlocks the lock variable
  2. It waits until someone signals the condition.
  3. it locks the lock variable again before it returns,

It does all this atomically. While the thread is waiting for the condition variable, the mutex is not locked - that way your producer thread can acquire the lock and safely set any variables shared between the consumers/producer.

It locks the mutex again upon return, so the consumer again can safely access the shared variables.

If you tried to manage locking/unlocking the mutex yourself, you would end up with race conditions betwen locking/unlocking the mutex and waiting/signalling the condition variable - this is why waiting for a condition variable is tied to a mutex - so it can be done atomically, without race conditions.

like image 150
nos Avatar answered Sep 23 '22 22:09

nos