std::weak_ptr 和相应的 std::shared_ptr 之间是否存在数据竞争?
Is there any data race between std::weak_ptr and corresponding std::shared_ptr?
根据cppref的说法,跨多个线程访问shared_ptr
const
成员是安全的。但是,当我们有一个对应于shared_ptr
的weak_ptr
时,这种说法是否有效?
作为示例,假设以下代码:
#include <memory>
#include <iostream>
#include <thread>
std::shared_ptr<int> sp;
std::weak_ptr<int> gw;
int main()
{
sp = std::make_shared<int>(42);
gw = sp;
auto th1 = std::thread([]{
for (int i = 0; i < 200; i++) {
if (sp.use_count() > 1) {
std::cout << i << "n";
std::this_thread::yield();
}
}
});
auto th2 = std::thread([]{
for (int i = 0; i < 20; i++) {
if (auto l = gw.lock()) {
std::cout << "locked ->" << l.use_count() << "n";
std::this_thread::yield();
}
}
});
th1.join();
th2.join();
}
此代码创建 2 个线程。一个检查shared_ptr()
use_count()
,这是一种const
方法,另一个使用lock()
来锁定weak_ptr()
这也是一种const
方法。但实际上,当我在weak_ptr
上调用lock
时,我实际上增加了shared_ptr
的引用计数,除非引用计数在内部受到保护,否则这不是线程安全的。我想知道在这种情况下我是否会进行数据竞赛。按照标准,这应该是线程安全的吗?
是的。引用计数器是原子计数器,因此示例中没有数据争用。
话虽如此,std::shared_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> 有什么区别?