避免重入代码C ++ 11中的死锁

时间:2017-08-09 02:57:12

标签: c++11 deadlock reentrancy

我正在努力重构一些遭受死锁的遗留代码。主要有两个根本原因:

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()操作期间读取树,这是不需要的行为。

1 个答案:

答案 0 :(得分:1)

从C ++ 11开始,您可以使用std::recursive_mutex,它允许拥有线程调用locktry_lock而不阻塞/报告失败,而其他线程将阻塞{{ 1}} /在lock上接收false,直到拥有线程调用try_lock的次数与之前调用unlock / lock的次数相同。