6
所以我有一个简单的cow_ptr
。它看起来是这样的:使用shared_ptr写复制
template<class T, class Base=std::shared_ptr<T const>>
struct cow_ptr:private Base{
using Base::operator*;
using Base::operator->;
using Base::operator bool;
// etc
cow_ptr(std::shared_ptr<T> ptr):Base(ptr){}
// defaulted special member functions
template<class F>
decltype(auto) write(F&& f){
if (!unique()) self_clone();
Assert(unique());
return std::forward<F>(f)(const_cast<T&>(**this));
}
private:
void self_clone(){
if (!*this) return;
*this = std::make_shared<T>(**this);
Assert(unique());
}
};
这样可以保证它拥有一个非const T
,并确保它是unique
当.write([&](T&){})
s到它。
c++17弃用.unique()
似乎表明此设计存在缺陷。
我猜测,如果我们开始与在线程A 1
一个cow_ptr<int> ptr
,它传递给线程B,使其具有唯一性,其修改为2
,通过ptr
回读它的线程A
,我们已经产生了种族条件。
我该如何解决这个问题?我可以简单地在write
中添加内存障碍吗?哪一个?还是这个问题更根本?
由于x86内存一致性超出了C++的要求,x86上的症状可能性较低吗?