多线程场景下调用shared_from_this是否为线程安全操作?
核心结论
只要持有对象的std::shared_ptr已经完成初始化,多线程并发调用shared_from_this属于线程安全操作,你给出的示例代码中多线程调用A::clone()是可行的。
依据说明
cppreference提到的逻辑是准确的:shared_from_this等价于用成员变量weak_this(std::enable_shared_from_this的私有std::weak_ptr成员)构造std::shared_ptr,线程安全性的依据来自两点:
- C++标准明确规定:对同一个
std::weak_ptr对象,多线程并发执行拷贝构造、或者通过它构造std::shared_ptr的操作是线程安全的,这类操作属于只读操作,不会修改weak_this本身的状态,不存在数据竞争。 std::enable_shared_from_this的私有weak_this成员,只会在第一个指向该对象的std::shared_ptr构造时被写入一次,初始化完成后永远不会被修改,后续所有shared_from_this调用都只有读操作,没有写冲突。
注意事项
有两个边界情况需要注意,和线程安全无关但会导致调用失败:
- 调用
shared_from_this前必须保证已经存在至少一个持有该对象的std::shared_ptr,否则会抛出std::bad_weak_ptr异常。 - 不要在对象的构造函数内部调用
shared_from_this,此时指向对象的std::shared_ptr还未完成构造,weak_this还没有被初始化。 - 如果在第一个
std::shared_ptr构造的同时,其他线程就调用了shared_from_this,此时存在读写冲突,不属于线程安全场景,这类场景在实际开发中非常少见,只要保证对象完全构造完成、被shared_ptr持有后再交给多线程使用就可以避免。
内容的提问来源于stack exchange,提问作者for_stack
相关产品推荐
相关产品推荐

