Yak*_*ont 8 c++ copy-on-write memory-barriers c++17
所以我有一个简单的cow_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());
}
};
Run Code Online (Sandbox Code Playgroud)
这可以保证它拥有一个非常量T并确保它在unique何时出现.write([&](T&){}).
在C++ 17的折旧.unique()似乎表明这种设计是有缺陷的.
我猜测如果我们从线程A中的cow_ptr<int> ptrwith 开始1,将它传递给线程B,使其唯一,修改它2,传ptr回它并在线程中读取它A我们已经生成了竞争条件.
我该如何解决?我可以简单地添加内存屏障write吗?哪一个?或者问题更根本?
由于x86内存的一致性超出了C++的要求,x86上的症状是否会降低?
我认为弃用这个的想法是它不能被错误地使用,就像你有这样的代码:
if(sp.unique()) {
// some deinitialisation
} else {
// somebody else will deinitialise.
}
Run Code Online (Sandbox Code Playgroud)
如果同时运行两次,则可能无法取消初始化。
在你的具体情况下,我认为没有问题,因为
我认为访问内存的命令不存在任何其他问题,因为计数器shared_ptr是原子的。
我可能只是切换到use_count == 1可能带有适当的评论