为什么lock_guard可以通过unique_lock获得一个已经锁定的互斥锁?-仍然有问题

why lock_guard can get an already locked mutex by unique_lock? - still questions

本文关键字:lock 锁定 有问题 一个 unique 可以通过 guard 为什么      更新时间:2023-10-16

我正在研究这个例子。我找到了这个问题,并以为我会得到答案,但我仍然有一个问题。

为了方便,我把代码贴在这里:

std::mutex m;
std::condition_variable cv;
std::string data;
bool ready = false;
bool processed = false;
void worker_thread()
{
    // Wait until main() sends data
    std::cout << "------------------------n";
    std::unique_lock<std::mutex> lk(m);
    cv.wait(lk, []{return ready;});
    // after the wait, we own the lock.
    std::cout << "Worker thread is processing datan";
    data += " after processing";
    // Send data back to main()
    processed = true;
    std::cout << "Worker thread signals data processing completedn";
    // Manual unlocking is done before notifying, to avoid waking up
    // the waiting thread only to block again (see notify_one for details)
    lk.unlock();
    cv.notify_one();
}
int main()
{
    std::thread worker(worker_thread);
    data = "Example data";
    // send data to the worker thread
    {
        std::lock_guard<std::mutex> lk(m);
        ready = true;
        std::cout << "main() signals data ready for processingn";
    }
    cv.notify_one();
    // wait for the worker
    {
        std::unique_lock<std::mutex> lk(m);
        cv.wait(lk, []{return processed;});
    }
    std::cout << "Back in main(), data = " << data << 'n';
    worker.join();
    return 0;
}

语句std::unique_lock<std::mutex> lk(m);不应该阻塞主线程,因为互斥体mworker_thread锁定?如果是,在这个例子中,它后面的语句cv.wait(lk, []{return processed;});不是不必要的吗?当主线程可以锁定互斥锁时,processed已经为true。

调用wait将在等待期间解锁互斥锁。参见http://en.cppreference.com/w/cpp/thread/condition_variable/wait。

编辑:这在你链接到的问题的答案中明确说明:https://stackoverflow.com/a/32030975/212870

EDIT 2:"当主线程可以锁定互斥锁时,processed将已经为真"是不正确的。工作线程可能还没有启动,或者即使启动了,也可能没有看到ready设置。

如果readyfalse, cv.wait(lk, []{return ready;});行执行以下操作:

  1. 解锁互斥锁lk

  2. 阻塞等待通知的线程

  3. 当通知到达时,解除线程阻塞并锁定互斥锁lk

因此主线程不会阻塞std::lock_guard<std::mutex> lk(m);,因为互斥锁被工作线程解锁了。