std::atomic<std::shared_ptr>
定义在头文件 <memory> 中 |
||
template< class T > struct std::atomic<std::shared_ptr<T>>; |
(自 C++20 起) | |
对 std::atomic 的部分模板特化,针对 std::shared_ptr<T>,允许用户以原子方式操作 shared_ptr
对象。
如果多个执行线程访问同一个 std::shared_ptr 对象,而没有进行同步,并且其中任何访问使用了 shared_ptr 的非常量成员函数,那么就会发生数据竞争,除非所有这些访问都通过 std::atomic<std::shared_ptr> 的实例进行(或者,从 C++20 开始已弃用,通过 独立函数 对 std::shared_ptr 进行原子访问)。
关联的 use_count
增加保证是原子操作的一部分。关联的 use_count
减少在原子操作之后进行,但不要求是原子操作的一部分,除非是当在失败的 CAS 中覆盖 expected 时 use_count
发生改变。任何关联的删除和释放都在原子更新步骤之后进行,并且不是原子操作的一部分。
请注意,shared_ptr
的控制块是线程安全的:不同的非原子 std::shared_ptr 对象可以使用可变操作(例如 operator= 或 reset)由多个线程同时访问,即使这些实例是副本,并在内部共享相同的控制块。
类型 T 可以是不完整类型。
[edit] 成员类型
成员类型 | 定义 |
value_type
|
std::shared_ptr<T> |
[edit] 成员函数
所有非特化的 std::atomic 函数也由此特化提供,并且没有其他成员函数。
constexpr atomic() noexcept = default; |
(1) | |
constexpr atomic( std::nullptr_t ) noexcept : atomic() {} |
(2) | |
atomic( std::shared_ptr<T> desired ) noexcept; |
(3) | |
atomic( const atomic& ) = delete; |
(4) | |
void operator=( const atomic& ) = delete; |
(1) | |
void operator=( std::shared_ptr<T> desired ) noexcept; |
(2) | |
void operator=( std::nullptr_t ) noexcept; |
(3) | |
bool is_lock_free() const noexcept; |
||
如果此类型的对象的所有原子操作都是无锁的,则返回 true,否则返回 false。
void store( std::shared_ptr<T> desired, std::memory_order order = std::memory_order_seq_cst ) noexcept; |
||
原子地将 *this 的值替换为 desired 的值,就像通过 p.swap(desired) 一样,其中 p 是底层的 std::shared_ptr<T>。内存根据 order 排序。如果 order 是 std::memory_order_consume、std::memory_order_acquire 或 std::memory_order_acq_rel,则行为未定义。
std::shared_ptr<T> load( std::memory_order order = std::memory_order_seq_cst ) const noexcept; |
||
原子地返回底层共享指针的副本。内存根据 order 排序。如果 order 是 std::memory_order_release 或 std::memory_order_acq_rel,则行为未定义。
std::shared_ptr<T> exchange( std::shared_ptr<T> desired, std::memory_order order = std::memory_order_seq_cst ) noexcept; |
||
原子地将底层的 std::shared_ptr<T> 替换为 desired,就像通过 p.swap(desired) 一样,其中 p 是底层的 std::shared_ptr<T>,并返回 p 在交换之前立即具有的值的副本。内存根据 order 排序。这是一个原子读-修改-写操作。
bool compare_exchange_strong( std::shared_ptr<T>& expected, std::shared_ptr<T> desired, std::memory_order success, std::memory_order failure ) noexcept; |
(1) | |
bool compare_exchange_weak( std::shared_ptr<T>& expected, std::shared_ptr<T> desired, std::memory_order success, std::memory_order failure ) noexcept; |
(2) | |
bool compare_exchange_strong( std::shared_ptr<T>& expected, std::shared_ptr<T> desired, std::memory_order order = std::memory_order_seq_cst ) noexcept; |
(3) | |
bool compare_exchange_weak( std::shared_ptr<T>& expected, std::shared_ptr<T> desired, std::memory_order order = std::memory_order_seq_cst ) noexcept; |
(4) | |
use_count
的更新是此原子操作的一部分,尽管写入本身(以及任何后续的释放/销毁)并不需要是原子操作。fail_order
与 order 相同,但 std::memory_order_acq_rel 被替换为 std::memory_order_acquire,std::memory_order_release 被替换为 std::memory_order_relaxed。fail_order
与 order 相同,但 std::memory_order_acq_rel 被替换为 std::memory_order_acquire,std::memory_order_release 被替换为 std::memory_order_relaxed。 void wait( std::shared_ptr<T> old, std::memory_order order = std::memory_order_seq_cst ) const noexcept; |
||
执行原子等待操作。
将 load(order) 与 old 进行比较,如果它们等效,则阻塞直到 *this 被 notify_one()
或 notify_all()
通知。重复此过程,直到 load(order) 发生变化。此函数保证只有在值发生变化时才会返回,即使底层实现发生虚假解除阻塞也是如此。
内存操作根据 order 顺序执行。如果 order 是 std::memory_order_release 或 std::memory_order_acq_rel,则行为未定义。
注意:如果两个 shared_ptr
存储相同的指针,并且它们要么共享所有权,要么都为空,则它们等效。
void notify_one() noexcept; |
||
执行原子通知操作。
如果有一个线程在 *this 上的原子等待操作(即 wait()
)中被阻塞,则解除阻塞至少一个这样的线程;否则不执行任何操作。
void notify_all() noexcept; |
||
执行原子通知操作。
解除阻塞所有在 *this 上的原子等待操作(即 wait()
)中被阻塞的线程,如果有的话;否则不执行任何操作。
[edit] 成员常量
此特化也提供唯一的标准 std::atomic 成员常量 is_always_lock_free
。
static constexpr bool is_always_lock_free = /*implementation-defined*/; |
||
[edit] 注意
特性测试 宏 | 值 | Std | 特性 |
---|---|---|---|
__cpp_lib_atomic_shared_ptr |
201711L | (C++20) | std::atomic<std::shared_ptr>
|
[edit] 示例
此部分不完整 原因:没有示例 |
[edit] 缺陷报告
以下行为变更缺陷报告被追溯应用于之前发布的 C++ 标准。
DR | 应用于 | 发布的行为 | 正确的行为 |
---|---|---|---|
LWG 3661 | C++20 | atomic<shared_ptr<T>> 不能从 nullptr 进行常量初始化 |
可以常量初始化 |
LWG 3893 | C++20 | LWG3661 使得 atomic<shared_ptr<T>> 不能从 nullptr_t 赋值 |
恢复可赋值性 |
[edit] 另请参阅
(C++11) |
用于 bool、整型、 浮点型、(自 C++20 起) 和指针类型的原子类模板及其特化 (类模板) |