【发布时间】:2019-06-07 20:35:00
【问题描述】:
我正在阅读有关 std::shared_ptr 的线程安全以及它提供的原子操作重载的信息,并且想知道它在类中的特定用例。
根据我对 shared_ptr 所承诺的线程安全性的理解,拥有这样的 get 方法是安全的:
class MyClass
{
std::shared_ptr<int> _obj;
public:
void start()
{
std::lock_guard<std::mutex> lock(_mtx);
_obj = std::make_shared<int>(1);
}
void stop()
{
std::lock_guard<std::mutex> lock(_mtx);
_obj.reset();
}
std::shared_ptr<int> get_obj() const
{
return _obj; //Safe (?)
}
};
getter 应该是安全的,因为对象将在任何线程的任何时候被初始化或为空。
但是如果我想在对象为空的情况下抛出异常,我需要在返回它之前检查它,我现在是否必须在那里加锁(因为可能会在 if 和 return 之间调用 stop() )?或者是否可以使用共享指针的锁定机制而不使用该方法中的锁定:
std::shared_ptr<int> get_obj() const
{
auto tmp = _obj;
if(!tmp) throw std::exception();
return tmp;
}
【问题讨论】:
-
get_obj与start和stop竞争。还需要保证前者不会与后者同时被调用。第二个版本与第一个版本具有相同的数据竞争 - 没有更好也没有更差。 -
另见stackoverflow.com/questions/20705304/…。不是完全重复,但答案与您的问题相关。
标签: c++ c++11 thread-safety shared-ptr race-condition