提升锁定互斥锁死锁

时间:2015-03-19 19:16:31

标签: multithreading boost

我有使用boost锁定机制来保护的代码。 问题是RecomputeStuff不仅可以从RemoveStuff中调用,而且还可以从另一个线程调用。我的问题是,使用这些boost锁定机制,修复RecomputeStuff的正确方法是什么?它现在的方式是僵局。

#include <boost/thread.hpp>

boost::shared_mutex values_mutex;

int globaldata;

class A
{
public:
    void RecomputeStuff();
    void RemoveStuff();
private:
    std::vector<std::string> data;
};

//Note, RecomputeStuff just reads from std::vector<std::string> data, but it also writes to other global stuff that RemoveStuff also writes to.
void A::RecomputeStuff()
{
    boost::upgrade_lock<boost::shared_mutex> lock(values_mutex);
    boost::upgrade_to_unique_lock<boost::shared_mutex>  unique_lock(lock);

    // this function reads std::vector<std::string> data
    // but also modifies `globaldata` that RemoveStuff also modifies.
}

void A::RemoveStuff()
{
    boost::upgrade_lock<boost::shared_mutex> lock(values_mutex);
    boost::upgrade_to_unique_lock<boost::shared_mutex>  unique_lock(lock);

    //here, remove stuff from std::vector<std::string> data
    //...then call RecomputeStuff

    RecomputeStuff();

    // modify `globaldata`
}

1 个答案:

答案 0 :(得分:1)

解决方案是将A::RecomputeStuff方法的未锁定代码移至单独的代码,并从A::RemoveStuffA::RecomputeStuff调用它。请参阅以下代码

boost::shared_mutex values_mutex;

int globaldata;

class A
{
private:
    void RecomputeStuffUnsafe();
public:
    void RecomputeStuff();
    void RemoveStuff();
private:
    std::vector<std::string> data;
};

void A::RecomputeStuffUnsafe()
{
    // this function reads std::vector<std::string> data
    // but also modifies `globaldata` that RemoveStuff also modifies.
}


//Note, RecomputeStuff just reads from std::vector<std::string> data, but it also writes to other global stuff that RemoveStuff also writes to.
void A::RecomputeStuff()
{
    boost::upgrade_lock<boost::shared_mutex> lock(values_mutex);
    boost::upgrade_to_unique_lock<boost::shared_mutex>  unique_lock(lock);

    RecomputeStuffUnsafe();
}

void A::RemoveStuff()
{
    boost::upgrade_lock<boost::shared_mutex> lock(values_mutex);
    boost::upgrade_to_unique_lock<boost::shared_mutex>  unique_lock(lock);

    //here, remove stuff from std::vector<std::string> data
    //...then call RecomputeStuff

    RecomputeStuffUnsafe();

    // modify `globaldata`
}

修改#00:

此外upgrade_lock有一个constructor,它接受​​try_to_lock_t标记。它看起来就像你要求的那样。