shared_ptr 上的原子操作
Atomic operations on shared_ptr
假设我有 shared_ptr<T> a
和两个线程 运行ning,其中一个是:
a.reset();
还有一个:
auto b = a;
如果操作是原子的,那么我要么得到两个空的 shared_ptrs 或 a
是空的并且 b
指向 a
所指向的内容.我对这两种结果都满意,但是,由于指令的交错,这些操作可能不是原子的。有什么办法可以保证吗?
更准确地说,我只需要 a.reset()
是原子的。
UPD:正如评论中指出的那样,如果我不更具体一点,我的问题就很愚蠢。可以使用互斥体实现原子性。但是,我想知道在shared_ptr
的实现层面上,事情是否已经得到解决。从 cppreference.com 开始,复制赋值和复制构造函数是线程安全的。所以 auto b = a
在没有锁的情况下 运行 是可以的。但是,从 this 开始,不清楚 a.reset()
是否也是线程安全的。
UPD1:如果有一些文档指定 shared_ptr 的哪些方法是线程安全的,那就太好了。来自 cppreference:
If multiple threads of execution access the same shared_ptr without synchronization and any of those accesses uses a non-const member function of shared_ptr then a data race will occur
我不清楚哪些方法是非常量。
让另一个线程使用一个weak_ptr
。弱指针上的 lock() 操作被记录为原子操作。
创建:
std::shared_ptr<A> a = std::make_shared<A>();
std::weak_ptr<A> a_weak = std::weak_ptr<A>(a);
线程 1:
a.reset();
线程 2:
b = a_weak.get();
if (b != nullptr)
{
...
}
std::shared_ptr<T>
就是有些人所说的 "thread-compatible" class,意思是只要 std::shared_ptr<T>
的每个 实例 在给定的时间点只能有一个线程调用其成员函数,这样的成员函数调用不会导致竞争条件,即使多个线程正在访问彼此共享所有权的 shared_ptr
s。
std::shared_ptr<T>
不是 线程安全的 class;一个线程调用 std::shared_ptr<T>
实例的非 const
方法而另一个线程也在访问 同一实例 是不安全的。如果您需要潜在的并发读取和写入而不是竞争,则使用互斥锁同步它们。
假设我有 shared_ptr<T> a
和两个线程 运行ning,其中一个是:
a.reset();
还有一个:
auto b = a;
如果操作是原子的,那么我要么得到两个空的 shared_ptrs 或 a
是空的并且 b
指向 a
所指向的内容.我对这两种结果都满意,但是,由于指令的交错,这些操作可能不是原子的。有什么办法可以保证吗?
更准确地说,我只需要 a.reset()
是原子的。
UPD:正如评论中指出的那样,如果我不更具体一点,我的问题就很愚蠢。可以使用互斥体实现原子性。但是,我想知道在shared_ptr
的实现层面上,事情是否已经得到解决。从 cppreference.com 开始,复制赋值和复制构造函数是线程安全的。所以 auto b = a
在没有锁的情况下 运行 是可以的。但是,从 this 开始,不清楚 a.reset()
是否也是线程安全的。
UPD1:如果有一些文档指定 shared_ptr 的哪些方法是线程安全的,那就太好了。来自 cppreference:
If multiple threads of execution access the same shared_ptr without synchronization and any of those accesses uses a non-const member function of shared_ptr then a data race will occur
我不清楚哪些方法是非常量。
让另一个线程使用一个weak_ptr
。弱指针上的 lock() 操作被记录为原子操作。
创建:
std::shared_ptr<A> a = std::make_shared<A>();
std::weak_ptr<A> a_weak = std::weak_ptr<A>(a);
线程 1:
a.reset();
线程 2:
b = a_weak.get();
if (b != nullptr)
{
...
}
std::shared_ptr<T>
就是有些人所说的 "thread-compatible" class,意思是只要 std::shared_ptr<T>
的每个 实例 在给定的时间点只能有一个线程调用其成员函数,这样的成员函数调用不会导致竞争条件,即使多个线程正在访问彼此共享所有权的 shared_ptr
s。
std::shared_ptr<T>
不是 线程安全的 class;一个线程调用 std::shared_ptr<T>
实例的非 const
方法而另一个线程也在访问 同一实例 是不安全的。如果您需要潜在的并发读取和写入而不是竞争,则使用互斥锁同步它们。