我有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()
应该原子地解锁mutex1
和mutex2
,并让线程进入休眠状态,直到cv
收到通知。
一旦mutex1
或mutex2
中的任何一个解锁,它仍然保证线程正在休眠并收听条件变量通知吗?
或者有可能一个互斥锁被解锁,第二个线程锁定它,发送通知,但第一个线程还没有睡觉和监听。因此通知从未到达,也没有发生唤醒。
答案 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