我正在努力重构一些遭受死锁的遗留代码。主要有两个根本原因:
1)同一个线程多次锁定相同的互斥锁,这应该不难解决,并且 2)代码偶尔会调用用户定义的函数,这些函数可以在顶层输入相同的代码。我需要在调用用户定义的函数之前锁定互斥锁,但我可能最终再次执行相同的代码,这将导致死锁情况。所以,我需要一些机制来告诉我互斥锁已被锁定,我不应该再锁定它。有什么建议吗?以下是代码所做内容的(非常)简要概述:
class TreeNode {
public:
// Assign a new value to this tree node
void set(const boost::any& value, boost::function<void, const TreeNode&> validator) {
boost::upgrade_lock<boost::shared_mutex> lock(mutexToTree_);
// call validator here
boost::upgrade_to_unique_lock<boost::shared_mutex> ulock(lock);
// set this TreeNode to value
}
// Retrieve the value of this tree node
boost::any get() {
boost::shared_lock<boost::shared_mutex> lock(mutexToTree_);
// get value for this tree node
}
private:
static boost::shared_mutex mutexToRoot_;
};
问题是验证器函数可以调用get()
,它会在同一个线程上锁定mutexToRoot_
。我可以将mutexToRoot_
修改为递归互斥,但这会阻止其他线程在get()
操作期间读取树,这是不需要的行为。
答案 0 :(得分:1)
从C ++ 11开始,您可以使用std::recursive_mutex
,它允许拥有线程调用lock
或try_lock
而不阻塞/报告失败,而其他线程将阻塞{{ 1}} /在lock
上接收false
,直到拥有线程调用try_lock
的次数与之前调用unlock
/ lock
的次数相同。