条件变量等待多个互斥锁

时间:2016-12-23 17:56:12

标签: c++ multithreading c++11 mutex condition-variable

我有std::condition_variable_any等待自定义锁定,该锁定由两个互斥锁组成(一个std::mutex和一个共享锁定std::shared_mutex)。它的unlock()操作只是按顺序解锁两个互斥锁。

例如(伪代码):

mutex mutex1;
shared_mutex mutex2;
condition_variable_any cv;
// acquiring the locks
DualLock lock(unique_lock(mutex1), shared_lock(mutex2));
// waiting
cv.wait(lock);

cv.wait()应该原子地解锁mutex1mutex2,并让线程进入休眠状态,直到cv收到通知。

一旦mutex1mutex2中的任何一个解锁,它仍然保证线程正在休眠并收听条件变量通知吗?

或者有可能一个互斥锁被解锁,第二个线程锁定它,发送通知,但第一个线程还没有睡觉和监听。因此通知从未到达,也没有发生唤醒。

1 个答案:

答案 0 :(得分:2)

如果DualLock符合BasicLockable的要求,则代码将按预期执行。如果没有,它就赢了。

BasicLockable引用为here

  

因此通知从未到达,也没有发生唤醒。

当正确使用条件变量时,这种情况永远不会发生。条件变量的唤醒不能被解释为事件的信号,因为condition_variable的文档解释了可能存在虚假的唤醒。

充其量,通知表明现在可能是测试您等待的条件的好时机(并且您可以通过安全知识确保测试受互斥锁保护)。< / p>

条件的状态和当前线程的阻塞状态是两个不同的问题。

这是一个更好的例子(假设DualLock正确模型BasicLockable):

bool condition_met = false;

mutex mutex1;
shared_mutex mutex2;
condition_variable_any cv;
// acquiring the locks
DualLock lock(unique_lock(mutex1), shared_lock(mutex2));
while(!condition_met)
{
    // waiting
    cv.wait(lock);
}
// whatever happens, you have the lock here

// ...work

lock.unlock();

你的通知人会通知这种方式:

DualLock lock(unique_lock(mutex1), shared_lock(mutex2));
condition_met = true;
lock.unlock();     // note the order: unlock mutex first...
cv.notify_all();   // ...then notify the condition variable