c++ - std::weak_ptr和对应的std::shared_ptr之间是否存在任何数据争用?

标签 c++ language-lawyer

根据cppref的说法,跨多个线程访问constshared_ptr成员是安全的。但是,当我们拥有与weak_ptr相对应的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指向的对象的可变操作不是原子的,所以必须加以保护,就像通过纯指针保护访问一样。

关于c++ - std::weak_ptr和对应的std::shared_ptr之间是否存在任何数据争用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62138000/

相关文章:

c - 为什么所有指向结构的指针都必须具有相同的大小?

c++ - 如何从 C++ 中的三个不同的 txt 文件中获取输入?

c++ - 如果构造函数因调用 std::make_shared 而崩溃,gdb 能否显示崩溃的详细信息

c++ - 如何从 std::vector 创建 QList

c++ - 为什么带有指针子对象的文字类类型的 constexpr 表达式不能是非类型模板参数

c++ - [expr.ref]/2 中的左值到右值转换

c++ - C++14 中 std::intializer_list 对象的预期生命周期是多少?

c++ - C++编译时关联数组

c++ - 关于sizeof用法的问题

c++ - 理论上,C++ 实现能否并行计算两个函数参数?