7

我试图找到答案一段时间,但我失败了。

让我们假设我们有一个shared_ptr从一个线程创建的。然后我们将它传递shared_ptr给另外 2 个线程(例如使用一些队列)。所以从这一刻起,有 2 个 original 的副本shared_ptr,指向同一个原始指针。shared_ptr两个所有者线程都将从队列中获取它们的副本。然后他们会将它传递给另一个线程或将其销毁。

问题是 - 它安全吗?原始指针是否会正确销毁(不会有引用计数器的竞争?) 在此处输入图像描述

4

3 回答 3

9

C++ 标准几乎不保证线程安全。的引用计数std::shared_ptr是唯一的例外:它保证表现为原子访问的变量。我相信这已编入第 20.7.2.2/4 节中的这句话中:

更改use_count()不反映可能引入数据竞争的修改。

boost::shared_ptr 提供相同的保证

shared_ptr 对象提供与内置类型相同级别的线程安全。一个 shared_ptr 实例可以被多个线程同时“读取”。不同的 shared_ptr 实例可以被多个线程同时“写入”……(即使这些实例是副本,并且在下面共享相同的引用计数。)

于 2012-07-15T12:29:53.650 回答
5

升压文档状态:

不同的 shared_ptr 实例可以被多个线程同时“写入”(使用诸如 operator= 或 reset 等可变操作访问)(即使这些实例是副本,并且在下面共享相同的引用计数。

(强调我的)

所以这里的关键是你是否在线程之间复制s 。boost::shared_ptr如果您创建副本(使用 s 的“安全”方式shared_ptr),您不必担心线程安全。但是,如果您通过shared_ptr引用或指针传递,因此shared_ptr在不同的线程中使用实际相同的,您将不得不担心线程安全,如文档中所述。

于 2012-07-15T12:57:05.733 回答
0

我想在多线程用例中对 boost 共享指针中的引用计数发表评论。评论是为了回答“boost共享指针引用计数中是否存在竞态条件?”的问题</p>

对于大多数主流编译器,至少在 boost 1.35 之后,我的简单回答是“不”。在 boost/detail/shared_count.hpp 中定义的名为“add_ref_copy”的 boost 实现。该函数将调用为各个编译器定义的相应原子函数。例如windows版本会调用“BOOST_INTERLOCKED_INCREMENT”以原子方式递增计数(详见详细信息\sp_counted_base_w32.hpp)。X86 的 Linux gcc 将调用 atomic_increment(... ) (详见详细信息\sp_counted_base_gcc_x86.hpp)。每个单独的编译器都实现了线程安全机制,以确保引用计数以有效的方式更新。有些代码甚至是用汇编编写的。

现在我的简单回答中有一个警告。您确实需要确保您的编译器包含在 boost 的祝福列表中,以实现多线程安全引用计数。如果您不确定是否可以定义“BOOST_SP_USE_PTHREADS”,它会驱动 boost 使用 pthread 库以原子方式更新引用计数(通过为 pthread 解决方案包含 boost/detail/sp_counted_base_pt.hpp)。

于 2014-04-19T19:39:10.667 回答