关于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评论里的说法是针对更普遍的并发场景,不是你的代码这种情况。
核心逻辑拆解
C++对weak_ptr线程安全的规定
- 不同线程操作不同的weak_ptr实例(哪怕指向同一个控制块),不用额外同步,是安全的。
- 多个线程操作同一个weak_ptr实例时,如果有线程用非const成员函数(比如
operator=、reset)修改它,且没有同步机制,就会触发数据竞争,导致未定义行为——这就是那条评论说的通用风险场景。
你的代码为什么安全
你在f4()里先完成g_w = p_s;的修改,再创建执行f3()的线程。这里std::thread的构造函数是一个同步点:主线程在构造线程对象之前的所有内存修改,对新线程都是可见的,而且主线程的写操作在子线程开始执行前就已经彻底完成,二者根本不会“同时执行”,自然不存在数据竞争。
那条评论的描述是针对写操作和读操作真的并发发生的场景(比如主线程在修改g_w的同时,子线程正在调用lock()),而你的代码通过线程构造这个同步点,把写和读的时序彻底分开了,所以不在风险范围内。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

