【发布时间】:2021-12-19 19:30:27
【问题描述】:
随着 C++ 语言规范在该领域的发展,有哪些推荐的策略来应对当前 C++ 编码并发访问 std::shared_ptr(-like) 和 std::unique_ptr(-like) 数据结构?
背景:
大约 2021 年,用于以并发友好的方式管理对 std::shared_ptr(-like) 和 std::unique_ptr(-like) 智能指针的访问的可用 C++ 语言结构不断变化。例如,C++20 对 std::atomic<std::shared_ptr> 的支持还没有在编译器中走得太远,但 C++20 规范告诉我们它即将到来。
我从事重要的多线程开发,需要能够通过(希望是无锁的)队列在线程之间传递智能指针(共享的和唯一的),并以各种线程安全的方式使用它们。我想以一种允许它在可用时轻松升级到现代语言功能的方式开发此代码。理想的情况是能够从中心位置轻松地进行此升级,例如更改 CPP 宏的定义并根据这些宏进行编码。
有没有人知道一个很好的策略(也许是一组好的 CPP 宏?)用于面向未来的并发代码?
[在一些好的 cmets 之后澄清编辑(谢谢大家)] 从我收集到的:
-
std::shared_ptr和std::unique_ptr的不同实例可以从不同的线程毫无问题地读取/写入,(例如当不同的实例被传递到不同的线程时)但它们指向的对象实例(或内存)多个线程可能无法同时安全地访问(因此,如果这是用例,您应该使用互斥锁或其他方法来访问指向的对象)。 [感谢 Alex Guteniev 的澄清] - std::shared_ptr 或 std::unique_ptr 的 SAME 实例可以使用(C++ 20 之前的:
std::atomic_load/store等和 C++20 之后的:std::atomic<std::shared_ptr>或std::atomic<std::unique_ptr>) 我的想法是,这可能是一个使用 CPP MACROS 的地方,例如 SHARED_GET、SHARED_SET、UNIQUE_GET、UNIQUE_SET,它们可以集中您从 C 开始需要进行的更改++17 到 C++20。 [感谢 NicolBolas 清楚地了解 C++20 中实际出现的内容。正如所指出的:我在下面的 cmets 中提供的链接已过时,因此请注意不要将其视为事实。]
- 如果您使用
std::move在线程之间传递std::unique_ptr以传递指向的内存,并使用队列来强制在任何给定时间只有一个线程可以访问,您可以同时使用std_unique 指针他们自己和线程中的指向内存,在没有任何互斥锁或其他防止资源争用的保护的情况下接收指针。
由于我在提问时感到困惑,所以我最初的问题可能令人困惑。现在我将问题改写为:我正在寻找一组访问 CPP 宏#defines,它可以检测 C++17 和 C++20,并将该版本的最干净/正确的定义用于以下操作:
-
MAKE_LOCAL_SHARED:创建/加载本地 std::shared_ptr 实例 线程可以读取/写入的公共/共享实例 与原作争执。它应该指向相同的内存 共同/共享的指向
-
BEGIN_USE_SHARED_TGT:创建一个 在其范围内持有
std::lock_guard/mutex本地std::shared_ptr实例的指向内存可以安全地 用过。 -
END_USE_SHARED_TGT:(可能只是一个右括号?)释放 使用指向内存完成时的
std::lock_guard/mutex -
BEGIN_USE_UNIQUE_TGT、END_USE_UNIQUE_TGT(同上
std::unique_ptr
【问题讨论】:
-
您可以使用模板化类型别名,如果支持则引用
std::atomic<std::shared_ptr<T>>,如果不支持,则可以使用替代阻止或特定于平台的解决方案。只需确保您的替代方案与std::atomic<std::shared_ptr<T>>接口兼容。 -
我猜未来的 C++ 将保持与当前对线程安全对象的要求的向后兼容性,除非线程模型发生变化以至于不可能向后兼容.
-
@Dave: "用于以并发友好的方式管理对 std::shared_ptr(-like) 和 std::unique_ptr(-like) 智能指针的访问的 C++ 语言结构正在不断变化”。不,他们不是。
atomic<shared_ptr>只是对 C++11 已经允许的东西的更好包装。即便如此,这有点无关紧要,因为atomic<shared_ptr>是关于允许多个线程对特定的shared_ptr对象进行原子访问,而不是它指向的对象。这与简单地将shared_ptr传递给另一个线程不同。 -
@NicolBolas, atomic
只是一个更好的 C++11 已经允许的包装器 - 不一定,因为atomic<shared_ptr>可以是无锁的。但否则同意 -
@Dave:没有
atomic_shared_ptr<Type>类型。那篇文章是 2017 年的,那是在谈论提案的早期版本。委员会采纳了该提案并将类型重命名为atomic<shared_ptr<T>>以明确它是什么。
标签: c++ multithreading shared-ptr c++20 unique-ptr