std::atomic_...<std::shared_ptr>
声明
// 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_load
、std::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_release
或 std::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_acquire
或 std::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) 相同,但可能出现伪失败。
如果 p
是 null pointer
,则所有这些函数都会调用未定义行为。
参数
p
, expected
- 指向 std::shared_ptr
的指针 r
, desired
- 一个 std::shared_ptr
mo
, success
, failure
- std::memory_order
类型的内存排序选择器。
异常
这些函数不抛出异常。
返回值
- 如果原子访问使用无锁指令实现,则返回
true
2,3) 指向的共享指针的副本。4,5) (无) 6,7) 原先指向的共享指针的副本 8,9,10,11) 如果共享指针等效且已执行交换,则为true
,否则为false
。
备注
这些函数通常使用互斥锁实现,存储在全局哈希表中,以指针值为键。
为避免数据竞争,一旦共享指针传递给任何这些函数,就不能非原子地访问它。特别是,您不能在不先将其原子地加载到另一个 shared_ptr
对象中,然后通过第二个对象解引用的情况下解引用这样的 shared_ptr
。
Concurrency TS 提供了原子智能指针类 atomic_shared_ptr
和 atomic_weak_ptr
,以替代这些函数的使用。
这些函数已被弃用,取而代之的是 std::atomic 模板
的特化:std::atomic<std::shared_ptr>
和 std::atomic<std::weak_ptr>
。(自 C++20 起)
示例
本节不完整
缺陷报告
以下改变行为的缺陷报告已追溯应用于先前发布的 C++ 标准。
DR | 应用于 | 发布时的行为 | 正确行为 |
---|---|---|---|
LWG 2980 | C++11 | 空的 shared_ptrs 永远不相等。 | 如果它们存储相同的指针值则相等。 |