使用std :: condition_variable之前锁定互斥锁

时间:2018-07-30 17:54:37

标签: multithreading c++11

我有一个与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();
//...

使用条件变量之前是否需要锁定互斥锁?或者它是线程安全的吗?

1 个答案:

答案 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和锁定的互斥锁之间的依赖关系。