弱指针的reset成员函数是原子的吗?

Posted

技术标签:

【中文标题】弱指针的reset成员函数是原子的吗?【英文标题】:Is reset member function for weak pointers atomic? 【发布时间】:2019-02-22 12:12:12 【问题描述】:

如果使用 std::make_shared 创建指向对象的共享指针,并使用指向它的弱指针作为观察者。当共享指针的引用计数为零时,对象不会被释放,因为弱指针使其保持活动状态。 (如果我没记错的话。)假设在对该弱指针调用成员函数 lock() 之后,结果证明它已经过期。现在程序员想调用reset()来触发对象的销毁,因为对象很大。

问题是:reset 是原子操作吗?如果答案是否定的,我的下一个问题是为什么标准不要求它是原子的。

【问题讨论】:

【参考方案1】:

只有在引用该对象的每个weak_ptr 被重置后,该对象才会被释放。

您不能从多个线程修改单个weak_ptr,因此单个weak_ptrreset 不需要是原子的。

【讨论】:

元数据对象只在弱引用计数为零时释放,而托管对象在强引用计数为零时释放,无论存在多少弱引用。【参考方案2】:

C++20 引入了一个辅助类 std::atomic,它保证引用

std::atomic 对 std::weak_ptr 的部分模板特化允许用户原子地操作 weak_ptr 对象。

如果多个执行线程访问同一个 std::weak_ptr 对象 没有同步,并且任何这些访问都使用非常量 weak_ptr 的成员函数,则将发生数据竞争,除非所有 这种访问是通过一个实例执行的 std::atomic>.

如果没有使用 C++20,请查看SO answer by Chris Jester-Young 以了解解决方法。

【讨论】:

以上是关于弱指针的reset成员函数是原子的吗?的主要内容,如果未能解决你的问题,请参考以下文章

C++|详解类成员指针:数据成员指针和成员函数指针及应用场合

c++类的成员函数指针如何转为普通指针

C++中怎么获取类的成员函数的函数指针

如何通过成员函数指针调用成员函数? [复制]

this指针

如何从另一个成员函数调用成员函数指针?