在 c++ 中,有没有等同于 Rust 的 Arc::try_unwrap?



这是一个c++生态系统的问题——尽管询问Rust是最简单的方法。

是否有线程安全/引用计数智能指针的稳定实现,支持"unwrap";它以线程安全的方式运行——在ref-count恰好为1的条件下,如https://doc.rust-lang.org/std/sync/struct.Arc.html#method.try_unwrap.

粗略地说,std::shared_ptr类似于ARC,但这个用例似乎不被支持,也没有直接实现(例如参见https://en.cppreference.com/w/cpp/memory/shared_ptr/use_count#Notes)。

std::shared_ptr的详尽API可以在线获得(参见cppreference),正如您所看到的,没有内置支持。

此外,由于std::weak_ptr的竞争条件的提升,不可能安全地使用use_countunique来实现这些功能——unique在c++ 17中被弃用,在c++ 20中被删除。

因此,该功能在std::shared_ptr中根本不可用。

可能有其他std::shared_ptr的实现提供这个功能——尽管Boost似乎没有。


use_count的注释所述,实现该函数的主要困难是weak_ptr提升时潜在的竞争条件。也就是,一个朴素的:

//  Susceptible to race-conditions, do not use!
if (pointer.use_count() == 1) {
return std::move(*pointer);
}
return std::nullopt;

不能工作,因为在检查和实际移动之间,一个新的共享所有者可能出现在另一个允许并发访问该值的线程中。

安全地使用此功能的唯一方法是:

  1. shared_ptr的实现从一开始就不支持弱指针。
  2. shared_ptr实现提供了它,并确保weak_ptr提升时不存在竞争条件。

我注意到后者通常需要锁定与weak_ptr提升相同的锁;这就是为什么它不能从外部提供的原因。

如果unique也保证不存在weak_ptr,则可以实现较弱的变体。尽管它并不严格等同于任何weak_ptr的存在都会导致失败,但在许多没有创建weak_ptr的场景中,它仍然是有用的。

最新更新