Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 等待多个互斥体的条件变量_C++_Multithreading_C++11_Mutex_Condition Variable - Fatal编程技术网

C++ 等待多个互斥体的条件变量

C++ 等待多个互斥体的条件变量,c++,multithreading,c++11,mutex,condition-variable,C++,Multithreading,C++11,Mutex,Condition Variable,我有一个std::condition\u变量\u any,它等待由两个互斥体组成的自定义锁(一个std::mutex和一个共享锁定std::shared\u mutex)。它的unlock()操作只是按顺序解锁两个互斥锁 例如(伪代码): cv.wait() 当mutex1或mutex2中的任何一个被解锁后,它仍然保证线程正在休眠并侦听条件变量通知吗 或者有可能一个互斥锁被解锁,第二个线程将其锁定,并发送通知,但第一个线程尚未睡眠和侦听。因此,通知从未到达,也未发生唤醒。如果DualLock满足

我有一个
std::condition\u变量\u any
,它等待由两个互斥体组成的自定义锁(一个
std::mutex
和一个共享锁定
std::shared\u mutex
)。它的
unlock()
操作只是按顺序解锁两个互斥锁

例如(伪代码):

cv.wait()

mutex1
mutex2
中的任何一个被解锁后,它仍然保证线程正在休眠并侦听条件变量通知吗


或者有可能一个互斥锁被解锁,第二个线程将其锁定,并发送通知,但第一个线程尚未睡眠和侦听。因此,通知从未到达,也未发生唤醒。

如果
DualLock
满足
BasicLockable
的要求,则代码将按预期执行。如果没有,就不会

基本时钟参考是

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

如果正确使用条件变量,则永远不会发生这种情况。条件变量的唤醒不能解释为事件的信号,因为条件变量的文档说明可能存在虚假唤醒

充其量,该通知表示现在可能是测试您正在等待的条件的好时机(您可以在知道测试受互斥锁保护的安全情况下这样做)

当前线程的状态和阻塞状态是两个独立的关注点

下面是一个更好的示例(假设DualLock模型基本上可以正确计时):

您的通知程序将通过以下方式通知:

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

因此,如果在等待线程上仍在执行
cv.wait()->DualLock::unlock()
时调用
cv.notify_all()
,则仍然可以保证
wait
不会开始睡眠,而是立即返回?@tmlen自定义互斥锁的lock方法必须按照概念进行操作(即完全锁定互斥锁、阻塞互斥锁或引发异常)。如果你做对了,上面的代码将永远有效。这里的复杂之处在于双锁的实现,而不是cv。如果
DualLock
不使用
std::lock
锁定互斥锁,则有死锁的危险。您的伪代码在构造
DualLock
的行中看起来有死锁的危险。
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