当调用condition_variable :: wait()时,解锁的unique_lock会发生什么?

时间:2016-08-11 18:30:08

标签: c++ multithreading

以下是C ++参考网站上的示例代码

#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;
}

如果我在调用wait()之前没有解锁unique_lock,一切正常。像:

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

我被告知

  

在阻塞线程时,函数(wait())自动调用lck.unlock(),允许其他锁定线程继续。

所以我想知道如果在调用wait()之前解锁unique_lock会怎么样。在我这样做之后,程序很奇怪,只有一两个线程完成了他们的工作(打印“线程X”消息),其他线程似乎永远被阻止(通过unique_lock?)

那些unique_locks发生了什么变化?或者它只是c ++的另一个未定义的行为,在wait()之前调用unlock()?

谢谢!

1 个答案:

答案 0 :(得分:3)

std::condition_variable::wait()

的文件中所述
  

如果当前线程未锁定lock.mutex(),则调用此函数是未定义的行为。