首页 > 解决方案 > std::condition_variable 和 std::mutex 是如何工作的?

问题描述

我正在阅读这个 std::condition_variable例子:

#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>
 
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::unique_lock<std::mutex> lk(m);
    cv.wait(lk, []{return ready;});
 
    // after the wait, we own the lock.
    std::cout << "Worker thread is processing data\n";
    data += " after processing";
 
    // Send data back to main()
    processed = true;
    std::cout << "Worker thread signals data processing completed\n";
 
    // 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 processing\n";
    }
    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();
}

让我们专注于开头:

std::thread worker(worker_thread);

在这里,我们开始工作,它将立即锁定互斥锁:

std::unique_lock<std::mutex> lk(m);
cv.wait(lk, []{return ready;});

然后,我们将互斥锁锁定在 main 上以更改ready

{
    std::lock_guard<std::mutex> lk(m);
    ready = true;
    std::cout << "main() signals data ready for processing\n";
}

但是我们怎么可能到达线路ready=true呢?互斥锁被m工作线程阻塞,因此该行将std::lock_guard<std::mutex> lk(m);等待互斥锁m解锁。据我了解,当互斥锁被锁定并且我们尝试锁定它时,我们将等到它被解锁。但是,它永远不会被解锁,因为工作线程正在等待,因此不会释放它。

标签: c++multithreadingconcurrencymutexcondition-variable

解决方案


在您附加的链接中,请注意以下内容

等待操作以原子方式释放互斥体并暂停线程的执行。

因此这条线

cv.wait(lk, []{return ready;});

释放互斥锁并暂停线程的执行,直到通知条件变量、超时到期(带wit_for())或发生虚假唤醒,因此线程被唤醒,并且互斥锁被原子地重新获取


推荐阅读