首页 > 解决方案 > 在使用 std::condition_variable 之前锁定互斥锁

问题描述

我有一个与std::condition_variable. 我阅读了很多关于它的内容,并且所有示例在使用之前都显示锁定互斥锁std::condition_variable

std::unique_lock<std::mutex> lock(mutex);
condition_variable.wait(lock);
//...

或者像这样:

std::unique_lock<std::mutex> lock(mutex);
condition_variable.notify_one();
//...

在使用条件变量之前是否需要锁定互斥锁还是线程安全的?

标签: multithreadingc++11

解决方案


正如评论中提到的,notify_one()不需要锁定互斥锁才能被调用,但wait(lock)确实如此。condition_variable有点不幸地命名,因为它提供了无条件等待某事发生的选项。更有用的版本是wait(lock, condition),其中线程在条件成立时才等待,否则根本不等待。

可以与酒店接待台进行类比,其中condition_variable工作线程中的接待员是接待员,互斥锁代表关键的共享资源(例如,用于预订的计算机),并且条件是顾客的存在。入住酒店涉及很多步骤,其中大部分可以由不同的接待员并行完成,但将您的详细信息输入计算机的一步不能 - 接待员必须一次使用计算机。

假设接待员上班时做的第一件事是检查计算机是否空闲(没有其他接待员在使用它)。在 的情况下wait(lock),接待员会这样做然后立即入睡,而不管前台是否有人在等待登记入住。在这种情况下,只有条件不成立(没有人在等待)wait(lock, condition)他们才会入睡)。

现在,如果接待员睡着了,他们不会注意到办公桌上有人在等待登记入住。这就是notify_one()- 唤醒接待员。唤醒接待员的动作不取决于计算机的状态(互斥锁)——即使所有接待员都醒着并且疯狂地签到人(想想 4 年-老人在没有监督的情况下离开了谁找到了铃铛……)。notify_one()唤醒一名接待员,同时notify_all()唤醒所有接待员。

这个类比并不完美,但它说明了 acondition_variable和锁定的互斥体之间的依赖关系。


推荐阅读