multithreading - 在使用 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();
//...
在使用条件变量之前是否需要锁定互斥锁还是线程安全的?
解决方案
正如评论中提到的,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
和锁定的互斥体之间的依赖关系。
推荐阅读
- python - 向 AWS rekognition 发送多个帧
- c# - 在资源管理器中右键单击将目录附加到exe
- go - travis 找不到我的包 golang
- javascript - await page.$$('.')).length 的值不正确
- sql-server - 将 varchar 值 \'08/01/1979\' 转换为数据类型 int 时转换失败
- nasm - NASM 逐字符读取文件
- apache-spark - 找不到关闭 Java Spark 会话的正确方法(使用 spark 版本 2.2.1)
- php - PHP - 从数据库中选择数据以获取第一条记录和其他 3 分钟值
- android - 为什么文本识别器无法运行?
- jsf-2 - JSF 通过 Ajax 刷新列表不正确