VinaLx
VinaLx

Reputation: 13

what happen to an unlocked unique_lock when condition_variable::wait() is called?

Here's an sample code on a C++ reference website

#include <chrono>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>

std::mutex mtx;
std::condition_variable cv;
bool ready = false;

void print_id(int id) {
    std::unique_lock<std::mutex> lck(mtx);
    while (!ready) {
        lck.unlock(); // by curiosity I unlock the lck
        cv.wait(lck);
    }
    std::cout << "thread " << id << '\n';
}

void go() {
    std::unique_lock<std::mutex> lck(mtx);
    ready = true;
    lck.unlock();
    cv.notify_all();
}

int main() {
    std::thread threads[10];
    for (int i = 0; i < 10; ++i)
        threads[i] = std::thread(print_id, i);
    go();
    for (auto &th : threads)
        th.join();

    return 0;
}

If I don't unlock the unique_lock before calling wait(), everything works normally. Like:

thread 9
thread 1
thread 2
thread 3
thread 4
thread 5
thread 6
thread 7
thread 8
thread 0

I've been told that

At the moment of blocking the thread, the function(wait()) automatically calls lck.unlock(), allowing other locked threads to continue.

So I wonder what if I unlock unique_lock before wait() is called.After I did that, the program behaved weirdly, only one or two threads complete their job(print the "thread X" message), other threads seem to be blocked (by the unique_lock?) forever.

What happened to those unique_locks? Or it's just another undefined behavior of c++ that calling unlock() before wait()?

Thanks!

Upvotes: 0

Views: 1160

Answers (1)

Slava
Slava

Reputation: 44238

As stated in documentation of std::condition_variable::wait()

Calling this function if lock.mutex() is not locked by the current thread is undefined behavior.

Upvotes: 3

Related Questions