boost :: shared_ptr在多个线程中使用它是否安全?

时间:2012-07-15 12:17:20

标签: c++ multithreading boost shared-ptr

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

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

问题是 - 它安全吗?原始指针是否会被正确销毁(没有竞争引用计数器?) enter image description here

3 个答案:

答案 0 :(得分:9)

C ++标准几乎不保证线程安全。 std::shared_ptr的引用计数是唯一的例外:它保证表现为原子访问的变量。我相信这在§20.7.2.2/ 4中的短语中已经编纂成了:

  

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

boost::shared_ptr offers the same guarantees

  

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

答案 1 :(得分:5)

boost docs州:

  

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

(强调我的)

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

答案 2 :(得分:0)

我想在多线程用例中的boost共享指针中发布我的注释用于引用计数。评论是回答“升压共享指针引用计数中是否存在任何竞争条件?”的问题。

对于大多数主流编译器,至少在提升1.35之后,我的简单回答是“否”。 boost / detail / shared_count.hpp中定义的boost实现名为“add_ref_copy”。该函数将调用为各个编译器定义的相应原子函数。例如,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)。