private std::unique_ptr<MyClass> myptr_;
LazyInit()
{
// Assume mutex lock. Skipping specifics since it is not relevant for this question
auto mylock = LOCK();
if(!myptr_)
{
// myptr_ is only initialized once ever. Once assigned it is never deleted till end of process.
myptr_ = make_unique<MyClass>();
}
// lock released when mylock goes out of scope.
}
Read()
{
// No locking here.
// Expectation: myptr_ is either null or valid value. Totally fine if myptr_ just got assigned, next call to Read will read the value.
if(myptr_)
{
myptr_->DoSomething();
}
}问:是否可以保证在执行Read()时,myptr_要么为null,要么具有有效值?(具体地说,就内存对齐而言,LazyInit中对myptr_的赋值是否是原子的?)假设LazyInit和Read都可以被多个线程调用。
根据下面的文档,看起来myptr_可能有一个垃圾值(不是null或有效值)。有人可以通过确认/否认我的理解来澄清这一点吗?
相关文档:( https://docs.microsoft.com/en-us/cpp/standard-library/thread-safety-in-the-cpp-standard-library?view=vs-2019 )“如果某个对象是由一个线程写入的,则必须保护同一线程或其他线程上对该对象的所有读取和写入操作。例如,给定一个对象A,如果线程1正在写入A,则必须阻止线程2读取或写入A。”
发布于 2020-07-20 05:14:42
不,这是不能保证的。std::unique_ptr的赋值操作符没有记录是线程安全的,bool操作符重载也没有记录是线程安全的。
当涉及到C++库时,除非明确指定为线程安全,否则就不是。除非可以在C++类或其方法中找到显式线程安全的文档,否则就不是线程安全的。
https://stackoverflow.com/questions/62985687
复制相似问题