C++ 与递归\u互斥体一起使用时,条件\u变量\u any的行为?
当将C++ 与递归\u互斥体一起使用时,条件\u变量\u any的行为?,c++,multithreading,c++11,boost,recursive-mutex,C++,Multithreading,C++11,Boost,Recursive Mutex,当将条件变量\u any与递归互斥体一起使用时,当条件变量\u any::wait正在等待时,递归互斥体通常可以从其他线程获取吗?我对Boost和C++11实现都感兴趣 这是我主要关注的用例: void bar(); boost::recursive_mutex mutex; boost::condition_variable_any condvar; void foo() { boost::lock_guard<boost::recursive_mutex> lock(
条件变量\u any
与递归互斥体一起使用时,当条件变量\u any::wait
正在等待时,递归互斥体
通常可以从其他线程获取吗?我对Boost和C++11实现都感兴趣
这是我主要关注的用例:
void bar();
boost::recursive_mutex mutex;
boost::condition_variable_any condvar;
void foo()
{
boost::lock_guard<boost::recursive_mutex> lock(mutex);
// Ownership level is now one
bar();
}
void bar()
{
boost::unique_lock<boost::recursive_mutex> lock(mutex);
// Ownership level is now two
condvar.wait(lock);
// Does this fully release the recursive mutex,
// so that other threads may acquire it while we're waiting?
// Will the recursive_mutex ownership level
// be restored to two after waiting?
}
void bar();
递归互斥互斥体;
boost::条件变量任何条件变量;
void foo()
{
boost::lock_guard lock(互斥锁);
//所有权级别现在是1
bar();
}
空条()
{
boost::唯一的锁(互斥锁);
//所有权级别现在是2
等待(锁);
//这是否完全释放了递归互斥体,
//这样其他线程可以在我们等待时获取它?
//递归\u互斥对象的所有权级别
//等待后恢复到两个?
}
通过对Boost文档的严格解释,我得出结论,条件变量\u any::wait
通常不会导致其他线程在等待通知时获取递归互斥锁
类条件变量\u任意
模板无效等待(锁定类型和锁定)
影响:
自动调用lock.unlock()
并阻止当前线程。当调用this->notify_one()
或
this->notify_all()
,或伪造。当线程被解锁时(对于
无论什么原因),通过调用lock.lock()
在等待调用返回之前。该锁也可由重新获取
如果函数带异常退出,则调用lock.lock()
因此condvar.wait(lock)
将调用lock.unlock
,这反过来调用mutex.unlock
,这会将所有权级别降低1(不一定降到零)
我已经编写了一个测试程序来证实我的上述结论(对于Boost和C++11):
#包括
#定义使用1
#如果使用(u BOOST),
#包括
#包括
#包括
#包括
#包括
名称空间lib=boost;
#否则
#包括
#包括
#包括
#包括
名称空间lib=std;
#恩迪夫
空心钢筋();
lib::递归_互斥体互斥体;
lib::条件变量任意条件变量;
int值=0;
void foo()
{
std::cout您可以通过向在互斥对象上运行的每个函数添加一个参数allowed\u unlock\u count
来修复此设计;对于allowed\u unlock\u count
,可以做出两种类型的保证:
(允许解锁深度)允许解锁计数
表示互斥锁的允许解锁深度
:调用者允许条
解锁互斥锁允许解锁计数
次。解锁后,不保证互斥锁的状态
(承诺解锁)允许的解锁计数
表示互斥锁的锁定深度
:调用者保证解锁互斥锁
的准确时间允许的解锁计数
将允许其他线程抓取互斥锁
对象
这些保证是函数的前置和后置条件
这里的条码取决于(承诺解锁):
// pre: mutex locking depth is allowed_unlock_count
void bar(int allowed_unlock_count)
{
// mutex locking depth is allowed_unlock_count
boost::unique_lock<boost::recursive_mutex> lock(mutex);
// mutex locking depth is allowed_unlock_count+1
// you might want to turn theses loops
// into an a special lock object!
for (int i=0; i<allowed_unlock_count; ++i)
mutex.unlock();
// mutex locking depth is 1
condvar.wait(lock); // other threads can grab mutex
// mutex locking depth is 1
for (int i=0; i<allowed_unlock_count; ++i)
mutex.lock();
// mutex locking depth is allowed_unlock_count+1
}
// post: mutex locking depth is allowed_unlock_count
//前置:允许互斥锁深度\u解锁\u计数
无效条(允许整数\u解锁\u计数)
{
//允许互斥锁深度\u解锁\u计数
boost::唯一的锁(互斥锁);
//允许互斥锁深度\u解锁\u计数+1
//你可能想把这些循环
//变成一个特殊的锁定对象!
对于(int i=0;iI在Boost文档中找不到任何关于混合条件变量\u any
和递归\u互斥体的信息。您期望(或希望)了吗调用wait
使互斥锁解锁?@curiousguy:是的,我有点这样做。这种行为会使它不太可能遇到死锁问题。调用函数呢?它是否期望bar()
解锁互斥锁?这里的问题是bar()的契约
允许它与其他地方的锁混淆。如果你想让这是你的设计,你需要让它非常明确。@curiousguy,我没有在我的任何东西中使用递归互斥锁
。我只是在这里读另一个问题时遇到它,想知道它如何与条件变量互操作。请解释一下下一票?我的推理有缺陷吗?不是我的下一票,但我支持它,因为答案并没有回答真正的问题,只是声称它是无法解决的。问题应该是“我如何使用递归互斥的条件变量”让人大吃一惊。+1表示假定的有意欢笑。+1 C++11规范与boost非常相似文档。这是一个罕见的情况下的推进遵循C++草案(当时)相反。condition\u variable\u any
是在中提出的,当时的规范要求递归锁的锁计数在进入等待时为1。具体的措辞已经改变,但意图没有改变。boost随后选择了它。
// pre: mutex locking depth is allowed_unlock_count
void bar(int allowed_unlock_count)
{
// mutex locking depth is allowed_unlock_count
boost::unique_lock<boost::recursive_mutex> lock(mutex);
// mutex locking depth is allowed_unlock_count+1
// you might want to turn theses loops
// into an a special lock object!
for (int i=0; i<allowed_unlock_count; ++i)
mutex.unlock();
// mutex locking depth is 1
condvar.wait(lock); // other threads can grab mutex
// mutex locking depth is 1
for (int i=0; i<allowed_unlock_count; ++i)
mutex.lock();
// mutex locking depth is allowed_unlock_count+1
}
// post: mutex locking depth is allowed_unlock_count