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

多线程读写共享数据时shared_ptr指向数据的安全性问询

问题解答

结论:读取得到的shared_ptr<Data>指向的对象有可能被损坏,核心取决于Data类的update方法以及你对该对象的后续访问是否是线程安全的。

为什么Buffer类自身的读写是安全的?

Buffer里的write和read方法都通过同一个std::mutex做了互斥同步:

  • 当read方法持有锁时,write方法会阻塞等待锁释放,反之亦然。
  • 这保证了read从database中拷贝shared_ptr<Data>的操作是原子性的,不会出现database中的元素被半修改的情况,你拿到的shared_ptr必然指向一个完整、有效的Data对象,也不会出现对象在拷贝过程中被销毁的问题(因为锁保护了database的修改,且shared_ptr的引用计数操作本身是原子的)。

风险点在哪里?

当read返回shared_ptr<Data>之后,这个对象的生命周期由shared_ptr的引用计数维护,但Buffer的mutex不再对该Data对象的访问做同步:

  • 后续write线程可以再次获取锁,找到同一个id对应的shared_ptr<Data>,然后调用data->update()。
  • 如果你的Data类的update方法没有内部同步机制(比如没有加锁、没有使用原子类型存储数据),同时读取线程在拿到shared_ptr后也在访问该Data对象的成员变量,那么这两个线程的操作就会形成竞态条件,直接导致Data对象的数据损坏。

怎么避免损坏?

  • 给Data类的所有修改和访问方法加上同步保护(比如内部加std::mutex);
  • 把Data类的成员变量换成原子类型(如果适合用原子操作实现逻辑);
  • 或者在read之后,不再允许write修改该Data对象(比如用不可变对象模式,修改时创建新的Data实例替换旧的)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 15:52:26