将std :: feek_ptr与std :: shared_ptr一起阴影
Using std::weak_ptr with std::shared_ptr for shadowing
cppreference上std::weak_ptr
的文档说
有效返回
expired() ? shared_ptr<T>() : shared_ptr<T>(*this)
,原子执行。
我的判断和其他答案已经确认以下内容不容易参加比赛
int main() {
auto s_ptr = std::make_shared<T>(...);
auto w_ptr = std::weak_ptr<T>{s_ptr};
auto one = std::thread{[&]() {
auto ptr = w_ptr.lock();
if (ptr) { ... }
}};
s_ptr = std::make_shared<T>(...);
one.join();
}
但是,这可以可靠地用于在程序中遮蔽计算吗?通过阴影,我的意思是这样的东西
auto s_ptr = std::make_shared<T>(...);
auto w_ptr = std::weak_ptr<T>{s_ptr};
// thread one
while (...) {
auto ptr = w_ptr.lock();
cout << "Value contained is " << *ptr << endl;
}
// thread two
while (...) {
// do the heavy computation on the side
auto new_value = fetch_new_value();
// then "atomically" swap
s_ptr = std::make_shared<T>(std::move(new_value));
}
这里令人困惑的部分是.lock()
返回的内容。它可以返回nullptr
吗?所有文档都表明该操作将被原子执行。不说这种相互排斥的含义。shared_ptr::operator=
中的指针是null的状态吗?weak_ptr
可以访问此状态吗?CPReference上shared_ptr::operator=
的文档似乎并未提及这一点。
一旦您的共享指针获得新值,您的弱指针将开始返回 nullptr
,原因是,一旦您的共享指针开始指向另一个对象,原始对象就会立即被销毁。
但是,由于交接是原子的,因此不会交换指针的行为。
(尽管w_ptr.lock()
返回的nullptr
值共享的指针不确定,并且可能会崩溃该程序)。
每当您的共享指针重置新值时,您都需要获得一个新的弱指针。但是,当您lock()
时,共享指针是否仍指向该新价值,您的弱指针是任何人的猜测。
与控制集团(参考计数)有关的任何事物都是原子。因此,获得新的弱指针是安全的,但不能保证指向任何东西(如果其他线程可以访问您的共享指针)。
此代码可以执行UB:
auto s_ptr = std::make_shared<T>(...);
auto w_ptr = std::weak_ptr<T>{s_ptr};
// thread one
while (...) { // A
auto ptr = w_ptr.lock(); // B
cout << "Value contained is " << *ptr << endl; // C
}
// thread two
while (...) {
// do the heavy computation on the side
auto new_value = fetch_new_value();
// then "atomically" swap
s_ptr = std::make_shared<T>(std::move(new_value)); // X
}
如果线程两个执行// X
在线程执行// B
之前,weak_ptr
不再是指任何数据。
.lock()
然后返回一个" null" shared_ptr
,您可以在// C
上取消。
如果您对ptr
的使用避免了无效,则不会显而易见。
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- std::具有相同基类的类的变体
- 引用 std::shared:ptr 以避免引用计数
- C++14 unique_ptr并使用已删除的函数'std::unique-ptr' unique_ptr错误
- 使用std :: String ptr的错误打印std :: String
- C++中的大小释放:全局运算符delete的正确行为是什么(void*ptr,std::size_t size)
- std::哈希表示无序映射中的唯一 PTR
- boost::shared_ptr和std::shared-ptr的同居
- 我可以用std::shared_ptr而不是boost::shared-ptr构建boost库吗
- 正确使用std智能指针以确保ptr安全
- 如何创建 std::string 包装器,它将 ptr 保留为 std::string 和 ptr 到创建该包装器实例的
- 为什么 std::string{ "const char ptr" } 有效?
- 为什么 gcc 4.9.0 中没有定义"void operator delete(void* ptr, std::size_t size) noexcept;"?
- 在 std::map 的值中使用非 ptr 是一种很好的做法吗
- 共享 PTR - C++:std::shared_ptr<T> 和 std::shared_ptr<T const> 有什么区别?