我有一个与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();
//...
使用条件变量之前是否需要锁定互斥锁?或者它是线程安全的吗?
答案 0 :(得分:1)
如评论中所述,notify_one()
不需要锁定的互斥体即可被调用,但wait(lock)
则需要。 condition_variable
的命名有点遗憾,因为它可以选择无条件地等待发生的事情。更有用的版本是wait(lock, condition),该线程仅在条件为不为true时才等待,否则根本不等待。
可以用一个酒店接待台进行类比,其中工作线程中的condition_variable
是接待员,互斥锁代表重要的共享资源(例如,用于进行预订的计算机),条件是赞助人的存在。入住酒店涉及很多步骤,其中大多数步骤可以由不同的接待员并行完成,但是将您的详细信息输入计算机的一个步骤不能完成-接待员必须一次使用一台计算机。>
假定接待员上班时要做的第一件事是检查计算机是否空闲(没有其他接待员在使用它)。在wait(lock)
的情况下,接待员会这样做,然后立即入睡,而不管是否有人在接待处等待签入。在wait(lock, condition)
的情况下他们只有在条件不是真的(没有人在等)的情况下才会入睡。
现在,如果接待员正在睡觉,那么当有人在办公桌旁等待登机时,他们不会注意到。notify_one()
就是这样做的-唤醒接待员。唤醒接待员的操作不取决于计算机的状态(互斥体)-即使所有接待员都醒了,您也可以一直在接待处敲钟,并检查有人疯了(想想一个4岁左右的孩子,没有监督就发现了钟声...)。 notify_one()
唤醒一位接待员,而notify_all()
唤醒所有人。
这个比喻不是完美的,但是它说明了condition_variable
和锁定的互斥锁之间的依赖关系。