简体   繁体   English

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

[英]boost::shared_ptr is it safe to use it in multiple threads?

I was trying to find the answer for some time but I failed. 我试图找到答案一段时间,但我失败了。

Lets assume that we have a shared_ptr created from one thread. 让我们假设我们有一个从一个线程创建的shared_ptr Then we pass this shared_ptr to another 2 threads (using some queue for example). 然后我们将此shared_ptr传递给另外2个线程(例如,使用某个队列)。 So from this moment there are 2 copies of the original shared_ptr , pointing to the same raw pointer. 所以从这一刻起,原始shared_ptr有两个副本,指向同一个原始指针。 Both owner threads will take their copies of this shared_ptr from the queue. 两个所有者线程都将从队列中获取此shared_ptr的副本。 Then they will pass it to another thread or will destroy it. 然后他们会将它传递给另一个线程或将其销毁。

Question is - is it safe? 问题是 - 它安全吗? Will the raw pointer destroyed correctly (there will be no race to reference counter?) 原始指针是否会被正确销毁(没有竞争引用计数器?) 在此输入图像描述

The C++ standard has almost no guarantees regarding thread safety. C ++标准几乎不保证线程安全。 The reference count of std::shared_ptr is the only exception: it's guaranteed to behave as an atomically accessed variable. std::shared_ptr的引用计数是唯一的例外:它保证表现为原子访问的变量。 I believe this is codified in this phrase in §20.7.2.2/4: 我认为这是在§20.7.2.2/ 4中的这句话中编纂的:

Changes in use_count() do not reflect modifications that can introduce data races. use_count()更改不反映可能引入数据use_count()修改。

boost::shared_ptr offers the same guarantees : boost::shared_ptr 提供相同的保证

shared_ptr objects offer the same level of thread safety as built-in types. shared_ptr对象提供与内置类型相同的线程安全级别。 A shared_ptr instance can be "read" … simultaneously by multiple threads. shared_ptr实例可以由多个线程同时“读取”...。 Different shared_ptr instances can be "written to"… simultaneosly by multiple threads (even when these instances are copies, and share the same reference count underneath.) 不同的shared_ptr实例可以被多个线程同时“写入”...(即使这些实例是副本,并在下面共享相同的引用计数。)

The boost docs state: 提升文档声明:

Different shared_ptr instances can be "written to" (accessed using mutable operations such as operator= or reset) simultaneosly by multiple threads ( even when these instances are copies, and share the same reference count underneath. ) 不同的shared_ptr实例可以被多个线程同时“写入”(使用诸如operator =或reset之类的可变操作访问)( 即使这些实例是副本,并在下面共享相同的引用计数。

(emphasis mine) (强调我的)

So the crux here is whether you copy the boost::shared_ptr s between threads or not. 所以这里的关键是你是否在线程之间复制 boost::shared_ptr If you create copies (the "safe" way to use shared_ptr s) you don't have any worries about thread-safety. 如果您创建副本(使用shared_ptr的“安全”方式),您不必担心线程安全。 If however you pass the shared_ptr by reference or pointer, and hence are using the actual same shared_ptr in different threads, you would have to worry about thread-safety, as described in the docs. 但是,如果您通过引用或指针传递shared_ptr ,因此在不同的线程中使用实际相同的shared_ptr ,则必须担心线程安全性,如文档中所述。

I would like to post my comment for the reference counting in the boost shared pointer in the multiple threads use cases. 我想在多线程用例中的boost共享指针中发布我的注释用于引用计数。 The comment is to answer the question that “is there any race condition in the boost shared pointer reference counting?” 评论是回答“升压共享指针引用计数中是否存在任何竞争条件?”的问题。

My simple answer is “No” at least after boost 1.35 for most mainstream compiler. 对于大多数主流编译器,至少在提升1.35之后我的简单回答是“否”。 The boost implementation called “add_ref_copy” defined in the boost/detail/shared_count.hpp. boost / detail / shared_count.hpp中定义的boost实现名为“add_ref_copy”。 This function will invoke the corresponding atomic function defined for individual compiler. 该函数将调用为各个编译器定义的相应原子函数。 For example, the windows version will call “BOOST_INTERLOCKED_INCREMENT” to increment the count in the atomic way (see details in detail\\sp_counted_base_w32.hpp). 例如,Windows版本将调用“BOOST_INTERLOCKED_INCREMENT”以原子方式递增计数(详细信息请参见\\ sp_counted_base_w32.hpp)。 And the Linux gcc for X86 will call atomic_increment(… ) (see details in detail\\sp_counted_base_gcc_x86.hpp). X86的Linux gcc将调用atomic_increment(...)(详见详细信息\\ sp_counted_base_gcc_x86.hpp)。 Each individual compiler implemented the thread-safe mechanism to make sure the reference counting update in an efficient way. 每个单独的编译器都实现了线程安全机制,以确保以有效的方式更新引用计数。 Some piece of code are even written in assembly. 有些代码甚至是用汇编语言编写的。

Now there is a caveats in my simple answer. 现在我的简单答案中有一个警告。 You really need to make sure your compiler is included in the boost's blessed list for multiple thread-safe reference counting. 您确实需要确保您的编译器包含在boost的祝福列表中,以进行多线程安全引用计数。 If you are not sure you can define “BOOST_SP_USE_PTHREADS” which drives boost to use the pthread library to make reference count update atomically (by including boost/detail/sp_counted_base_pt.hpp for pthread solution). 如果您不确定是否可以定义“BOOST_SP_USE_PTHREADS”来驱动boost以使用pthread库以原子方式进行引用计数更新(通过为pthread解决方案包含boost / detail / sp_counted_base_pt.hpp)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM