跳到主要内容

std::atomic_...<std::shared_ptr>

声明

Since C++11, Deprecated in C++20
// 1)
template< class T >
bool atomic_is_lock_free( const std::shared_ptr<T>* p );
// 2)
template< class T >
std::shared_ptr<T> atomic_load( const std::shared_ptr<T>* p );
// 3)
template< class T >
std::shared_ptr<T> atomic_load_explicit( const std::shared_ptr<T>* p,
std::memory_order mo );
// 4)
template< class T >
void atomic_store( std::shared_ptr<T>* p,
std::shared_ptr<T> r );
// 5)
template< class T >
void atomic_store_explicit( std::shared_ptr<T>* p,
std::shared_ptr<T> r,
std::memory_order mo);
// 6)
template< class T >
std::shared_ptr<T> atomic_exchange( std::shared_ptr<T>* p,
std::shared_ptr<T> r);
// 7)
template<class T>
std::shared_ptr<T> atomic_exchange_explicit( std::shared_ptr<T>* p,
std::shared_ptr<T> r,
std::memory_order mo);
// 8)
template< class T >
bool atomic_compare_exchange_weak( std::shared_ptr<T>* p,
std::shared_ptr<T>* expected,
std::shared_ptr<T> desired);
// 9)
template<class T>
bool atomic_compare_exchange_strong( std::shared_ptr<T>* p,
std::shared_ptr<T>* expected,
std::shared_ptr<T> desired);
// 10)
template< class T >
bool atomic_compare_exchange_strong_explicit( std::shared_ptr<T>* p,
std::shared_ptr<T>* expected,
std::shared_ptr<T> desired,
std::memory_order success,
std::memory_order failure);
// 11)
template< class T >
bool atomic_compare_exchange_weak_explicit( std::shared_ptr<T>* p,
std::shared_ptr<T>* expected,
std::shared_ptr<T> desired,
std::memory_order success,
std::memory_order failure);

如果多个执行线程在没有同步的情况下访问同一个 std::shared_ptr 对象,并且其中任何一个访问使用了 shared_ptr 的非 const 成员函数,则将发生数据竞争,除非所有此类访问都通过这些函数执行。这些函数是相应原子访问函数的重载(std::atomic_loadstd::atomic_store 等)。

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


确定 p 指向的共享指针是否支持无锁访问。


Equivalent to atomic_load_explicit(p, std::memory_order_seq_cst)


返回 p 指向的共享指针。与未特化的 std::atomic_load_explicit 一样,mo 不能是 std::memory_order_releasestd::memory_order_acq_rel


Equivalent to atomic_store_explicit(p, r, memory_order_seq_cst)


将共享指针 r 原子地存储到 p 指向的共享指针中,有效地执行 p->swap(r)。与未特化的 std::atomic_store_explicit 一样,mo 不能是 std::memory_order_acquirestd::memory_order_acq_rel


Equivalent to atomic_exchange_explicit(p, r, memory_order_seq_cst)


将共享指针 r 原子地存储到 p 指向的共享指针中,并返回 p 原先指向的值。有效地执行 p->swap(r),并在交换后返回 r 的副本。


Equivalent to atomic_compare_exchange_weak_explicit(p, expected, desired, std::memory_order_seq_cst, std::memory_order_seq_cst)


Equivalent to atomic_compare_exchange_strong_explicit(p, expected, desired, std::memory_order_seq_cst, std::memory_order_seq_cst)


比较 p 和 expected 指向的共享指针。如果它们等效(存储相同的指针值,并且要么共享同一对象的拥有权,要么都是空的),则使用 success 指定的内存排序约束将 desired 赋值给 *p,并返回 true。如果它们不等效,则使用 failure 指定的内存排序约束将 *p 赋值给 *expected,并返回 false


与 10) 相同,但可能出现伪失败。

如果 pnull pointer,则所有这些函数都会调用未定义行为。

参数

p, expected - 指向 std::shared_ptr 的指针 r, desired - 一个 std::shared_ptr mo, success, failure - std::memory_order 类型的内存排序选择器。

异常

这些函数不抛出异常。

返回值

  1. 如果原子访问使用无锁指令实现,则返回 true 2,3) 指向的共享指针的副本。4,5) (无) 6,7) 原先指向的共享指针的副本 8,9,10,11) 如果共享指针等效且已执行交换,则为 true,否则为 false

备注

这些函数通常使用互斥锁实现,存储在全局哈希表中,以指针值为键。

为避免数据竞争,一旦共享指针传递给任何这些函数,就不能非原子地访问它。特别是,您不能在不先将其原子地加载到另一个 shared_ptr 对象中,然后通过第二个对象解引用的情况下解引用这样的 shared_ptr

Concurrency TS 提供了原子智能指针类 atomic_shared_ptratomic_weak_ptr,以替代这些函数的使用。

这些函数已被弃用,取而代之的是 std::atomic 模板 的特化:std::atomic<std::shared_ptr>std::atomic<std::weak_ptr>。(自 C++20 起)

示例

本节不完整

缺陷报告

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

DR应用于发布时的行为正确行为
LWG 2980C++11空的 shared_ptrs 永远不相等。如果它们存储相同的指针值则相等。

std::atomic_...<std::shared_ptr>

声明

Since C++11, Deprecated in C++20
// 1)
template< class T >
bool atomic_is_lock_free( const std::shared_ptr<T>* p );
// 2)
template< class T >
std::shared_ptr<T> atomic_load( const std::shared_ptr<T>* p );
// 3)
template< class T >
std::shared_ptr<T> atomic_load_explicit( const std::shared_ptr<T>* p,
std::memory_order mo );
// 4)
template< class T >
void atomic_store( std::shared_ptr<T>* p,
std::shared_ptr<T> r );
// 5)
template< class T >
void atomic_store_explicit( std::shared_ptr<T>* p,
std::shared_ptr<T> r,
std::memory_order mo);
// 6)
template< class T >
std::shared_ptr<T> atomic_exchange( std::shared_ptr<T>* p,
std::shared_ptr<T> r);
// 7)
template<class T>
std::shared_ptr<T> atomic_exchange_explicit( std::shared_ptr<T>* p,
std::shared_ptr<T> r,
std::memory_order mo);
// 8)
template< class T >
bool atomic_compare_exchange_weak( std::shared_ptr<T>* p,
std::shared_ptr<T>* expected,
std::shared_ptr<T> desired);
// 9)
template<class T>
bool atomic_compare_exchange_strong( std::shared_ptr<T>* p,
std::shared_ptr<T>* expected,
std::shared_ptr<T> desired);
// 10)
template< class T >
bool atomic_compare_exchange_strong_explicit( std::shared_ptr<T>* p,
std::shared_ptr<T>* expected,
std::shared_ptr<T> desired,
std::memory_order success,
std::memory_order failure);
// 11)
template< class T >
bool atomic_compare_exchange_weak_explicit( std::shared_ptr<T>* p,
std::shared_ptr<T>* expected,
std::shared_ptr<T> desired,
std::memory_order success,
std::memory_order failure);

如果多个执行线程在没有同步的情况下访问同一个 std::shared_ptr 对象,并且其中任何一个访问使用了 shared_ptr 的非 const 成员函数,则将发生数据竞争,除非所有此类访问都通过这些函数执行。这些函数是相应原子访问函数的重载(std::atomic_loadstd::atomic_store 等)。

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


确定 p 指向的共享指针是否支持无锁访问。


Equivalent to atomic_load_explicit(p, std::memory_order_seq_cst)


返回 p 指向的共享指针。与未特化的 std::atomic_load_explicit 一样,mo 不能是 std::memory_order_releasestd::memory_order_acq_rel


Equivalent to atomic_store_explicit(p, r, memory_order_seq_cst)


将共享指针 r 原子地存储到 p 指向的共享指针中,有效地执行 p->swap(r)。与未特化的 std::atomic_store_explicit 一样,mo 不能是 std::memory_order_acquirestd::memory_order_acq_rel


Equivalent to atomic_exchange_explicit(p, r, memory_order_seq_cst)


将共享指针 r 原子地存储到 p 指向的共享指针中,并返回 p 原先指向的值。有效地执行 p->swap(r),并在交换后返回 r 的副本。


Equivalent to atomic_compare_exchange_weak_explicit(p, expected, desired, std::memory_order_seq_cst, std::memory_order_seq_cst)


Equivalent to atomic_compare_exchange_strong_explicit(p, expected, desired, std::memory_order_seq_cst, std::memory_order_seq_cst)


比较 p 和 expected 指向的共享指针。如果它们等效(存储相同的指针值,并且要么共享同一对象的拥有权,要么都是空的),则使用 success 指定的内存排序约束将 desired 赋值给 *p,并返回 true。如果它们不等效,则使用 failure 指定的内存排序约束将 *p 赋值给 *expected,并返回 false


与 10) 相同,但可能出现伪失败。

如果 pnull pointer,则所有这些函数都会调用未定义行为。

参数

p, expected - 指向 std::shared_ptr 的指针 r, desired - 一个 std::shared_ptr mo, success, failure - std::memory_order 类型的内存排序选择器。

异常

这些函数不抛出异常。

返回值

  1. 如果原子访问使用无锁指令实现,则返回 true 2,3) 指向的共享指针的副本。4,5) (无) 6,7) 原先指向的共享指针的副本 8,9,10,11) 如果共享指针等效且已执行交换,则为 true,否则为 false

备注

这些函数通常使用互斥锁实现,存储在全局哈希表中,以指针值为键。

为避免数据竞争,一旦共享指针传递给任何这些函数,就不能非原子地访问它。特别是,您不能在不先将其原子地加载到另一个 shared_ptr 对象中,然后通过第二个对象解引用的情况下解引用这样的 shared_ptr

Concurrency TS 提供了原子智能指针类 atomic_shared_ptratomic_weak_ptr,以替代这些函数的使用。

这些函数已被弃用,取而代之的是 std::atomic 模板 的特化:std::atomic<std::shared_ptr>std::atomic<std::weak_ptr>。(自 C++20 起)

示例

本节不完整

缺陷报告

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

DR应用于发布时的行为正确行为
LWG 2980C++11空的 shared_ptrs 永远不相等。如果它们存储相同的指针值则相等。