c++ - std::weak_ptr 和相应的 std::shared_ptr 之间是否存在数据竞争?
问题描述
根据 cppref,跨多个线程访问const
成员是安全的。shared_ptr
但是,当我们有weak_ptr
对应于 a 的a 时,这个陈述是否有效shared_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 个线程。其中一个检查use_count()
是shared_ptr()
一种const
方法,另一个lock()
用于锁定weak_ptr()
,这也是一种const
方法。但实际上,当我调用lock
时weak_ptr
,我实际上会增加引用计数,shared_ptr
除非引用计数在内部受到保护,否则它不是线程安全的。我想知道在这种情况下我是否会进行数据竞赛。按照标准,这应该是线程安全的吗?
解决方案
是的。引用计数器是原子的,因此您的示例中没有数据竞争。
话虽如此,对指向的对象的可变操作std::shared_ptr
不是原子的,因此必须保护它们,就像通过普通指针保护访问一样。
推荐阅读
- postgresql - 是否可以让 psql \copy 看到 csv 文件中的一行作为注释?
- .net - 注销后 Angular MSAL 重定向到 Microsoft 登录
- networking - 我需要在内部网络中使用 DHCP 吗?
- swift - 如何从新的、以编程方式创建的选项卡的视图控制器与窗口控制器通信?
- java - 使用流检测实体的多个属性的重复项
- c++ - Sorting a vector of pairs that correspond to row and column of matrix
- reactjs - 在 react-router 中使用 useRef 时,useRef.current 总是返回 undefined
- java - 无法在 CriteriaBuilder 构造方法中调用数据库函数
- angular - 尝试在 Ionic 中使用本机文件时,类型“FileOriginal”不可分配给“Provider”类型
- eclipse - Eclipse Juno 到 Photon 格式