提升锁定互斥锁死锁
boost locking mutex deadlocks
我有一些代码,我正试图使用升压锁定机制来保护它。 问题是RecomputeStuff不仅可以从RemoveStuff调用,还可以从另一个线程调用。我的问题是,使用这些boost锁定机制,正确的修复方法是什么重新计算东西?它现在的方式是死锁。
#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`
}
一个解决方案是将A::RecomputeStuff
方法的未锁定代码移到单独的代码中,并从A::RemoveStuff
和A::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 which accepts the try_to_lock_t 标签。它看起来像你要求的。
我有一些代码,我正试图使用升压锁定机制来保护它。 问题是RecomputeStuff不仅可以从RemoveStuff调用,还可以从另一个线程调用。我的问题是,使用这些boost锁定机制,正确的修复方法是什么重新计算东西?它现在的方式是死锁。
#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`
}
一个解决方案是将A::RecomputeStuff
方法的未锁定代码移到单独的代码中,并从A::RemoveStuff
和A::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 which accepts the try_to_lock_t 标签。它看起来像你要求的。