std::atomic 智能指针的部分模板特化
Partial template specialization of std::atomic for smart pointers
背景
自 C++11 起,std::shared_ptr
上的原子操作可以通过 std::atomic_...
找到的方法 here 完成,因为如下所示的部分特化是不可能的:
std::atomic<std::shared_ptr<T>>
这是因为 std::atomic
仅接受 TriviallyCopyable 类型,并且 std::shared_ptr
(或 std::weak_ptr
)不可简单复制。
但是,从 C++20 开始,这些方法已被弃用,并被 std::atomic
用于 std::shared_ptr
的部分模板专业化所取代,如 here 所述。
问题
我不确定
- 为什么
std::atomic_...
被替换了。
- 用于启用
std::atomic
智能指针的部分模板专业化的技术。
针对 atomic<shared_ptr>
或类似性质的一些提议解释了多种原因。特别值得注意的是 P0718,它告诉我们:
The C++ standard provides an API to access and manipulate specific shared_ptr
objects atomically, i.e., without introducing data races when the same object is manipulated from multiple threads without further synchronization. This API is fragile and error-prone, as shared_ptr
objects manipulated through this API are indistinguishable from other shared_ptr
objects, yet subject to the restriction that they may be manipulated/accessed only through this API. In particular, you cannot dereference such a shared_ptr
without first loading it into another shared_ptr
object, and then dereferencing through the second object.
N4058 解释了关于您必须如何实施此类事情的性能问题。由于 shared_ptr
的大小通常大于单个指针,因此原子访问通常必须使用自旋锁来实现。因此,要么每个 shared_ptr
实例都有一个自旋锁,即使它从未被原子地使用过,要么这些原子函数的实现必须为单个对象提供 table 自旋锁。或者使用全局自旋锁。
None 如果你有一个专用于原子的类型,这些都是问题。
atomic<shared_ptr>
实现可以使用 atomic<T>
的常用技术,当 T
太大而不适合 CPU 原子操作时。他们通过法令绕过 TriviallyCopyable 限制:标准要求它们存在并且是原子的,所以实现就是这样。 C++ 实现不必遵循与常规 C++ 程序相同的规则。
背景
自 C++11 起,std::shared_ptr
上的原子操作可以通过 std::atomic_...
找到的方法 here 完成,因为如下所示的部分特化是不可能的:
std::atomic<std::shared_ptr<T>>
这是因为 std::atomic
仅接受 TriviallyCopyable 类型,并且 std::shared_ptr
(或 std::weak_ptr
)不可简单复制。
但是,从 C++20 开始,这些方法已被弃用,并被 std::atomic
用于 std::shared_ptr
的部分模板专业化所取代,如 here 所述。
问题
我不确定
- 为什么
std::atomic_...
被替换了。 - 用于启用
std::atomic
智能指针的部分模板专业化的技术。
针对 atomic<shared_ptr>
或类似性质的一些提议解释了多种原因。特别值得注意的是 P0718,它告诉我们:
The C++ standard provides an API to access and manipulate specific
shared_ptr
objects atomically, i.e., without introducing data races when the same object is manipulated from multiple threads without further synchronization. This API is fragile and error-prone, asshared_ptr
objects manipulated through this API are indistinguishable from othershared_ptr
objects, yet subject to the restriction that they may be manipulated/accessed only through this API. In particular, you cannot dereference such ashared_ptr
without first loading it into anothershared_ptr
object, and then dereferencing through the second object.
N4058 解释了关于您必须如何实施此类事情的性能问题。由于 shared_ptr
的大小通常大于单个指针,因此原子访问通常必须使用自旋锁来实现。因此,要么每个 shared_ptr
实例都有一个自旋锁,即使它从未被原子地使用过,要么这些原子函数的实现必须为单个对象提供 table 自旋锁。或者使用全局自旋锁。
None 如果你有一个专用于原子的类型,这些都是问题。
atomic<shared_ptr>
实现可以使用 atomic<T>
的常用技术,当 T
太大而不适合 CPU 原子操作时。他们通过法令绕过 TriviallyCopyable 限制:标准要求它们存在并且是原子的,所以实现就是这样。 C++ 实现不必遵循与常规 C++ 程序相同的规则。