You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于std::weak_ptr跨线程读写是否存在数据竞争的问询

关于std::weak_ptr跨线程读写的未定义行为疑问解答

先看你提供的代码:

std::weak_ptr<int> g_w;

void f3()
{
    std::shared_ptr<int> l_s3 = g_w.lock(); // 读取g_w
    if (l_s3)
    {
        ;//.....
    }
}

void f4()
{
    std::shared_ptr<int> p_s = std::make_shared<int>(1);
    g_w = p_s; // 修改g_w

    std::thread th(f3);
    th.detach();
}

你的判断其实是对的,这段代码不存在数据竞争,Stack Overflow评论里的说法是针对更普遍的并发场景,不是你的代码这种情况。

核心逻辑拆解

  1. C++对weak_ptr线程安全的规定

    • 不同线程操作不同的weak_ptr实例(哪怕指向同一个控制块),不用额外同步,是安全的。
    • 多个线程操作同一个weak_ptr实例时,如果有线程用非const成员函数(比如operator=、reset)修改它,且没有同步机制,就会触发数据竞争,导致未定义行为——这就是那条评论说的通用风险场景。
  2. 你的代码为什么安全
    你在f4()里先完成g_w = p_s;的修改,再创建执行f3()的线程。这里std::thread的构造函数是一个同步点:主线程在构造线程对象之前的所有内存修改,对新线程都是可见的,而且主线程的写操作在子线程开始执行前就已经彻底完成,二者根本不会“同时执行”,自然不存在数据竞争。

那条评论的描述是针对写操作和读操作真的并发发生的场景(比如主线程在修改g_w的同时,子线程正在调用lock()),而你的代码通过线程构造这个同步点,把写和读的时序彻底分开了,所以不在风险范围内。

内容的提问来源于stack exchange,提问作者John

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 11:50:19