std::atomic<std::shared_ptr>

来自cppreference.com
< cpp‎ | memory‎ | shared ptr
 
 
工具库
通用工具
日期和时间
函数对象
格式化库 (C++20)
(C++11)
关系运算符 (C++20 中弃用)
整数比较函数
(C++20)(C++20)(C++20)
(C++20)
swap 与类型运算
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
常用词汇类型
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)
初等字符串转换
(C++17)
(C++17)
 
动态内存管理
未初始化内存算法
受约束的未初始化内存算法
分配器
垃圾收集支持
(C++11)(C++23 前)
(C++11)(C++23 前)
(C++11)(C++23 前)
(C++11)(C++23 前)
(C++11)(C++23 前)
(C++11)(C++23 前)



 
 
在标头 <memory> 定义
template <class T> struct std::atomic<std::shared_ptr<T>>;
(C++20 起)

std::atomicstd::shared_ptr<T> 的部分模板特化允许用户原子地操纵 shared_ptr 。

若多个执行线程同时访问同一 std::shared_ptr 对象而不同步,且任何这些访问使用了 shared_ptr 的非 const 成员函数,则将出现数据竞争,除非通过 std::atomic<std::shared_ptr>> 的实例进行所有访问(或通过从 C++20 起弃用的孤立函数对 std::shared_ptr 进行原子访问)。

关联 use_count 的自增保证是原子操作的一部分。关联 use_count 的自减后序于原子操作,但不要求是原子操作的一部分,除非在覆写失败的 CAS 中的 expected 时, use_count 更改。任何关联删除和解分配后序于原子更新步骤,且不是原子操作的一部分。

注意 shared_ptr 的控制块是线程安全的:多个线程能同时用可变操作,例如 operator= 或 reset ,访问不同的非原子 std::shared_ptr 对象,即使这些实例互为副本,于内部共享同一控制块。

类型 T 可为不完整类型。

成员类型

成员类型 定义
value_type std::shared_ptr<T>

成员函数

此特化提供所有非特化的 std::atomic 的成员函数,不提供附加成员函数。

atomic<shared_ptr<T>>::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)
1,2) 初始化底层 shared_ptr<T> 为空值。
3) 初始化底层 shared_ptr<T>desired 的副本。同任何 std::atomic 类型,初始化不是原子操作。
4) 原子类型不可复制/移动构造。

atomic<shared_ptr<T>>::operator=

void operator=(const atomic&) = delete;
(1)
void operator=(std::shared_ptr<T> desired) noexcept;
(2)
void operator=( std::nullptr_t ) noexcept;
(3)
1) 原子类型不可复制/移动构造。
2) 值赋值,等价于 store(desired)
3) 重置原子共享指针为空指针值。等价于 store(nullptr);

atomic<shared_ptr<T>>::is_lock_free

bool is_lock_free() const noexcept;

若此类型所有对象上的原子操作为免锁则返回 true ,否则返回 false

atomic<shared_ptr<T>>::store

void store(std::shared_ptr<T> desired,
           std::memory_order order = std::memory_order_seq_cst) noexcept;

如同用 p.swap(desired) ,原子地以 desired 的值替换 *this 的值,其中 p 是底层的 std::shared_ptr<T> 。按照 order 排序内存。若 orderstd::memory_order_consumestd::memory_order_acquirestd::memory_order_acq_rel 则行为未定义。

atomic<shared_ptr<T>>::load

原子地返回底层共享指针的副本。按照 order 排序内存。若 order 不是 std::memory_order_releasestd::memory_order_acq_rel 则行为未定义。

atomic<shared_ptr<T>>::operator std::shared_ptr<T>

operator std::shared_ptr<T>() const noexcept;

等价于 return load();

atomic<shared_ptr<T>>::exchange

std::shared_ptr<T> exchange(std::shared_ptr<T> desired,
                            std::memory_order order = std::memory_order_seq_cst) noexcept;

如同用 p.swap(desired) ,原子地以 desired 替换底层 std::shared_ptr<T> ,其中 p 为底层 std::shared_ptr<T> ,并返回该 p 的值的副本。按照 order 排序内存。这是原子读修改写操作。

atomic<shared_ptr<T>>::compare_exchange_weak, compare_exchange_strong

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)
1) 若底层 std::shared_ptr<T> 存储同 expectedT* 并与之共享所有权,或若底层指针和 expected 均为空,则从 desired 赋值给底层 std::shared_ptr<T> 并返回 true ,按照 success 排序内存;否则从底层 std::shared_ptr<T> 赋值给 expected 并返回 false ,按照 failure 排序内存。若 failurestd::memory_order_releasestd::memory_order_acq_rel 则行为未定义。成功时,操作为 *this 上的读修改写操作,而且在原子更新后不访问 expected 。失败时,操作为 *this 上的原子加载操作,并更新 expected 为从原子对象读取的既存值。这个对 expected 的 use_count 的更新是原子操作的一部分,尽管不要求写入自身(以及任何后继的解分配/析构)是其一部分。
2)(1) ,但允许虚假地失败。
3) 等价于: return compare_exchange_strong(expected, desired, order, fail_order); ,其中 fail_orderorder 相同,除了 std:memory_order_acq_rel 被替换为 std::memory_order_acquire ,而 std::memory_order_release 被替换为 std::memory_order_relaxed
4) 等价于: return compare_exchange_weak(expected, desired, order, fail_order); ,其中 fail_orderorder 相同,除了 std::memory_order_acq_rel 被替换为 std::memory_order_acquirestd::memory_order_release 被替换为 std::memory_order_relaxed

atomic<shared_ptr<T>>::wait

void wait(std::shared_ptr<T> old
          std::memory_order order = std::memory_order_seq_cst) const noexcept;

进行原子等待操作。

比较 load(order)old ,而若它们等价则阻塞直至 *thisnotify_one()notify_all() 提醒。重复此操作直至 load(order) 更改。此函数保证仅若值更改才返回,即使底层实现虚假地除阻。

按照 order 排序内存。若 orderstd::memory_order_releasestd::memory_order_acq_rel 则行为未定义。

注解:若二个 shared_ptr 存储同一指针,且要么共享所有权要么都为空,则它们等价。

atomic<shared_ptr<T>>::notify_one

void notify_one() noexcept;

进行原子提醒操作。

若有一个线程在 *this 上的原子等待操作(即 wait() )中阻塞,则除阻至少一个这种线程,否则不做任何事。

atomic<shared_ptr<T>>::notify_all

void notify_all() noexcept;

进行原子提醒操作。

除阻所有在 *this 上的原子等待操作(即 wait() )中阻塞的线程,若存在;否则不做任何事。

成员常量

此特化亦提供标准 std::atomic 仅有的成员常量 is_always_lock_free

atomic<shared_ptr<T>>::is_always_lock_free

static constexpr bool is_always_lock_free = /*implementation-defined*/;

注解

功能特性测试 标准 备注
__cpp_lib_atomic_shared_ptr 201711L (C++20) std::atomic<std::shared_ptr>

示例

缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

缺陷报告 应用于 出版时的行为 正确行为
LWG 3661 C++20 atomic<shared_ptr<T>> 不可从 nullptr 常量初始化 使之可常量初始化
LWG 3893 C++20 LWG3661 使得 atomic<shared_ptr<T>> 不能从 nullptr_t 赋值 恢复为可赋值

参阅

(C++11)
atomic 类模板及其针对布尔、整型和指针类型的特化
(类模板)