跳到主要内容

std::atomic<std::shared_ptr>

定义于头文件 <memory>

声明

自 C++20 起
template< class T >
struct std::atomic<std::shared_ptr<T>>;

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 中覆盖预期时的 use_count 更改。任何相关的删除和去分配都在原子更新步骤之后排序,并且不是原子操作的一部分。

请注意,shared_ptr 的控制块是线程安全的:即使这些实例是副本,并且在内部共享相同的控制块,多个线程也可以同时使用可变操作(例如 operator=reset)访问不同的非原子 std::shared_ptr 对象。

类型 T 可以是不完整类型。

成员类型

成员类型定义
value_typestd::shared_ptr<T>

成员函数

所有未特化的 std::atomic 函数也由此特化提供,没有额外的成员函数。


atomic<shared_ptr<T>>::atomic

constexpr atomic() noexcept = default;                      ()
constexpr atomic( std::nullptr_t ) noexcept : atomic() {} ()
atomic( std::shared_ptr<T> desired ) noexcept; ()
atomic( const atomic& ) = delete; (4)

1,2) 将底层的 shared_ptr<T> 初始化为 null 值。3) 将底层的 shared_ptr<T> 初始化为 desired 的副本。与任何 std::atomic 类型一样,初始化不是原子操作。4) 原子类型不可复制/移动构造。


atomic<shared_ptr<T>>::operator=

void operator=( const atomic& ) = delete;                   ()
void operator=( std::shared_ptr<T> desired ) noexcept; ()
  1. 原子类型不可复制/移动赋值。
  2. 值赋值,等同于 store(desired)

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;

原子地将 *this 的值替换为 desired 的值,如同通过 p.swap(desired),其中 p 是底层的 std::shared_ptr<T>。内存根据 order 进行排序。如果 order 是 std::memory_order_consumestd::memory_order_acquirestd::memory_order_acq_rel,则行为未定义。


atomic<shared_ptr<T>>::load

std::shared_ptr<T> load( std::memory_order order = std::memory_order_seq_cst ) const noexcept;

原子地返回底层共享指针的副本。内存根据 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;

原子地将底层的 std::shared_ptr<T> 替换为 desired,如同通过 p.swap(desired),其中 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> 存储与 expected 相同的 T* 并与其共享所有权,或者如果底层和 expected 都为空,则将 desired 的值赋给底层的 std::shared_ptr<T>,返回 true,并根据 success 对内存进行排序,否则将底层的 std::shared_ptr<T> 的值赋给 expected,返回 false,并根据 failure 对内存进行排序。如果 failurestd::memory_order_releasestd::memory_order_acq_rel,则行为未定义。在 success 时,操作是对 *this 的原子读-修改-写操作,并且在原子更新后不访问 expected。在 failure 时,操作是对 *this 的原子加载操作,并且 expected 用从原子对象读取的现有值进行更新。对 expecteduse_count 的此更新是此原子操作的一部分,尽管写入本身(以及任何后续的去分配/销毁)不要求是。

  2. 与 (1) 相同,但可能会出现伪失败。

  3. 等同于:return compare_exchange_strong(expected, desired, order, fail_order);,其中 fail_orderorder 相同,但 std::memory_order_acq_rel 被替换为 std::memory_order_acquirestd::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_ptrs 等价,如果它们存储相同的指针并且共享所有权或都为空。


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*/;

备注

|特征测试宏|值|Std|注释| |::|::|::| |__cpp_lib_atomic_shared_ptr |201711L|(C++20)| std::atomic<std::shared_ptr>|

示例

本节不完整

缺陷报告

以下改变行为的缺陷报告已追溯应用于先前发布的 C++ 标准。

|DR|已应用到|已发布行为|正确行为| |::|::|::| |LWG 3661| C++20| atomic<shared_ptr<T>> 不能从 nullptr 进行常量初始化|可进行常量初始化|

std::atomic<std::shared_ptr>

定义于头文件 <memory>

声明

自 C++20 起
template< class T >
struct std::atomic<std::shared_ptr<T>>;

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 中覆盖预期时的 use_count 更改。任何相关的删除和去分配都在原子更新步骤之后排序,并且不是原子操作的一部分。

请注意,shared_ptr 的控制块是线程安全的:即使这些实例是副本,并且在内部共享相同的控制块,多个线程也可以同时使用可变操作(例如 operator=reset)访问不同的非原子 std::shared_ptr 对象。

类型 T 可以是不完整类型。

成员类型

成员类型定义
value_typestd::shared_ptr<T>

成员函数

所有未特化的 std::atomic 函数也由此特化提供,没有额外的成员函数。


atomic<shared_ptr<T>>::atomic

constexpr atomic() noexcept = default;                      ()
constexpr atomic( std::nullptr_t ) noexcept : atomic() {} ()
atomic( std::shared_ptr<T> desired ) noexcept; ()
atomic( const atomic& ) = delete; (4)

1,2) 将底层的 shared_ptr<T> 初始化为 null 值。3) 将底层的 shared_ptr<T> 初始化为 desired 的副本。与任何 std::atomic 类型一样,初始化不是原子操作。4) 原子类型不可复制/移动构造。


atomic<shared_ptr<T>>::operator=

void operator=( const atomic& ) = delete;                   ()
void operator=( std::shared_ptr<T> desired ) noexcept; ()
  1. 原子类型不可复制/移动赋值。
  2. 值赋值,等同于 store(desired)

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;

原子地将 *this 的值替换为 desired 的值,如同通过 p.swap(desired),其中 p 是底层的 std::shared_ptr<T>。内存根据 order 进行排序。如果 order 是 std::memory_order_consumestd::memory_order_acquirestd::memory_order_acq_rel,则行为未定义。


atomic<shared_ptr<T>>::load

std::shared_ptr<T> load( std::memory_order order = std::memory_order_seq_cst ) const noexcept;

原子地返回底层共享指针的副本。内存根据 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;

原子地将底层的 std::shared_ptr<T> 替换为 desired,如同通过 p.swap(desired),其中 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> 存储与 expected 相同的 T* 并与其共享所有权,或者如果底层和 expected 都为空,则将 desired 的值赋给底层的 std::shared_ptr<T>,返回 true,并根据 success 对内存进行排序,否则将底层的 std::shared_ptr<T> 的值赋给 expected,返回 false,并根据 failure 对内存进行排序。如果 failurestd::memory_order_releasestd::memory_order_acq_rel,则行为未定义。在 success 时,操作是对 *this 的原子读-修改-写操作,并且在原子更新后不访问 expected。在 failure 时,操作是对 *this 的原子加载操作,并且 expected 用从原子对象读取的现有值进行更新。对 expecteduse_count 的此更新是此原子操作的一部分,尽管写入本身(以及任何后续的去分配/销毁)不要求是。

  2. 与 (1) 相同,但可能会出现伪失败。

  3. 等同于:return compare_exchange_strong(expected, desired, order, fail_order);,其中 fail_orderorder 相同,但 std::memory_order_acq_rel 被替换为 std::memory_order_acquirestd::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_ptrs 等价,如果它们存储相同的指针并且共享所有权或都为空。


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*/;

备注

|特征测试宏|值|Std|注释| |::|::|::| |__cpp_lib_atomic_shared_ptr |201711L|(C++20)| std::atomic<std::shared_ptr>|

示例

本节不完整

缺陷报告

以下改变行为的缺陷报告已追溯应用于先前发布的 C++ 标准。

|DR|已应用到|已发布行为|正确行为| |::|::|::| |LWG 3661| C++20| atomic<shared_ptr<T>> 不能从 nullptr 进行常量初始化|可进行常量初始化|