是boost shared_ptr吗? 线程安全?

发布于 2024-07-16 03:56:36 字数 1196 浏览 8 评论 0原文

我有关于 boost::shared_ptr 的问题。

有很多线程。

using namespace boost;

class CResource
{
  // xxxxxx
}

class CResourceBase
{
public:
   void SetResource(shared_ptr<CResource> res)
   {
     m_Res = res;
   }

   shared_ptr<CResource> GetResource()
   {
      return m_Res;
   }
private:
   shared_ptr<CResource> m_Res;
}

CResourceBase base;

//----------------------------------------------
// Thread_A:
    while (true)
    {
       //...
       shared_ptr<CResource> nowResource = base.GetResource();
       nowResource.doSomeThing();
       //...
    }

// Thread_B:
    shared_ptr<CResource> nowResource;
    base.SetResource(nowResource);
    //...

Q1

如果Thread_A不关心nowResource是最新的,这部分代码会有问题吗?

我的意思是,当 Thread_B 没有完全 SetResource() 时,Thread_A 通过 GetResource() 得到错误的智能点?

Q2

线程安全是什么意思?

如果我不关心资源是否是最新的,那么 shared_ptr会吗? nowResource 在释放 nowResource 时使程序崩溃,或者该问题是否会破坏 shared_ptr

I have a question about boost::shared_ptr<T>.

There are lots of thread.

using namespace boost;

class CResource
{
  // xxxxxx
}

class CResourceBase
{
public:
   void SetResource(shared_ptr<CResource> res)
   {
     m_Res = res;
   }

   shared_ptr<CResource> GetResource()
   {
      return m_Res;
   }
private:
   shared_ptr<CResource> m_Res;
}

CResourceBase base;

//----------------------------------------------
// Thread_A:
    while (true)
    {
       //...
       shared_ptr<CResource> nowResource = base.GetResource();
       nowResource.doSomeThing();
       //...
    }

// Thread_B:
    shared_ptr<CResource> nowResource;
    base.SetResource(nowResource);
    //...

Q1

If Thread_A do not care the nowResource is the newest, will this part of code have problem?

I mean when Thread_B do not SetResource() completely, Thread_A get a wrong smart point by GetResource()?

Q2

What does thread-safe mean?

If I do not care about whether the resource is newest, will the shared_ptr<CResource> nowResource crash the program when the nowResource is released or will the problem destroy the shared_ptr<CResource>?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

躲猫猫 2024-07-23 03:56:36

boost::shared_ptr 提供一定程度的线程安全性。 引用计数以线程安全的方式进行操作(除非您配置 boost 来禁用线程支持)。

因此,您可以复制 shared_ptr 并正确维护 ref_count 。 在多线程中无法安全执行的操作是从多个线程修改实际的 shared_ptr 对象实例本身(例如从多个线程调用 reset() )。 因此您的使用并不安全 - 您正在多个线程中修改实际的 shared_ptr 实例 - 您需要拥有自己的保护。

在我的代码中,shared_ptr 通常是本地变量或按值传递的参数,因此没有问题。 将它们从一个线程转移到另一个线程我通常使用线程安全队列。

当然,这些都没有解决访问 shared_ptr 指向的对象的线程安全性 - 这也取决于您。

boost::shared_ptr<> offers a certain level of thread safety. The reference count is manipulated in a thread safe manner (unless you configure boost to disable threading support).

So you can copy a shared_ptr around and the ref_count is maintained correctly. What you cannot do safely in multiple threads is modify the actual shared_ptr object instance itself from multiple threads (such as calling reset() on it from multiple threads). So your usage is not safe - you're modifying the actual shared_ptr instance in multiple threads - you'll need to have your own protection.

In my code, shared_ptr's are generally locals or parameters passed by value, so there's no issue. Getting them from one thread to another I generally use a thread-safe queue.

Of course none of this addresses the thread safety of accessing the object pointed to by the shared_ptr - that's also up to you.

把回忆走一遍 2024-07-23 03:56:36

来自 boost 文档

shared_ptr 对象提供相同的功能
内置线程安全级别
类型。 shared_ptr 实例可以是
“read”(仅使用 const 访问
操作)同时由多个
线程。 不同 shared_ptr
实例可以“写入”
(使用可变操作访问
例如 operator= 或重置)
由多个线程同时进行
(即使这些实例是副本,
并共享相同的引用计数
下面。)

任何其他同时访问都会导致未定义的行为。

因此您的使用并不安全,因为它使用 m_res 的同时读写。 boost 文档中的示例 3 也说明了这一点。

您应该使用单独的 互斥体< /a> 保护对 SetResource/GetResourcem_res 的访问。

From the boost documentation:

shared_ptr objects offer the same
level of thread safety as built-in
types. A shared_ptr instance can be
"read" (accessed using only const
operations) simultaneously by multiple
threads. Different shared_ptr
instances can be "written to"
(accessed using mutable operations
such as operator= or reset)
simultaneously by multiple threads
(even when these instances are copies,
and share the same reference count
underneath.)

Any other simultaneous accesses result in undefined behavior.

So your usage is not safe, since it uses simultaneous read and write of m_res. Example 3 in the boost documentation also illustrates this.

You should use a separate mutex that guards the access to m_res in SetResource/GetResource.

自由如风 2024-07-23 03:56:36

嗯,tr1::shared_ptr(基于 boost)文档讲述了一个不同的故事,这意味着资源管理是线程安全的,而对资源的访问则不是。

“...

线程安全

中不推荐使用采用 auto_ptr 参数的构造函数。

C++0x 独有的功能包括:右值引用/移动支持、分配器支持、别名构造函数、make_shared 和 allocate_shared。此外,在 C++0x模式 Boost shared_ptr 文档的线程安全部分说“shared_ptr 对象提供与内置类型相同级别的线程安全性。”即使这些实例共享引用计数(例如,

shared_ptr a), 实现也必须确保对单独的 shared_ptr 实例的并发更新是正确的。 (新A);
共享指针 b(a);

// 线程 1 // 线程 2

a.reset(); b.重置();

动态分配的对象必须由其中一个线程销毁。 弱引用让事情变得更加有趣。 用于实现shared_ptr的共享状态必须对用户透明,并且必须始终保留不变量。 共享状态的关键部分是强引用计数和弱引用计数。 对这些的更新需要是原子的并且对所有线程可见,以确保托管资源的正确清理(毕竟,这是shared_ptr的工作!)在多处理器系统上,可能需要内存同步,以便引用计数更新和销毁的托管资源是无竞争的。

...“


http://gcc.gnu.org/onlinedocs /libstdc++/manual/memory.html#std.util.memory.shared_ptr

Well, tr1::shared_ptr (which is based on boost) documentation tells a different story, which implies that resource management is thread safe, whereas access to the resource is not.

"...

Thread Safety

C++0x-only features are: rvalue-ref/move support, allocator support, aliasing constructor, make_shared & allocate_shared. Additionally, the constructors taking auto_ptr parameters are deprecated in C++0x mode.

The Thread Safety section of the Boost shared_ptr documentation says "shared_ptr objects offer the same level of thread safety as built-in types." The implementation must ensure that concurrent updates to separate shared_ptr instances are correct even when those instances share a reference count e.g.

shared_ptr a(new A);
shared_ptr b(a);

// Thread 1 // Thread 2

a.reset(); b.reset();

The dynamically-allocated object must be destroyed by exactly one of the threads. Weak references make things even more interesting. The shared state used to implement shared_ptr must be transparent to the user and invariants must be preserved at all times. The key pieces of shared state are the strong and weak reference counts. Updates to these need to be atomic and visible to all threads to ensure correct cleanup of the managed resource (which is, after all, shared_ptr's job!) On multi-processor systems memory synchronisation may be needed so that reference-count updates and the destruction of the managed resource are race-free.

..."

see
http://gcc.gnu.org/onlinedocs/libstdc++/manual/memory.html#std.util.memory.shared_ptr

濫情▎り 2024-07-23 03:56:36

m_Res 不是线程安全的,因为它同时读/写,
你需要 boost::atomic_store/load 函数来保护它。

//--- Example 3 ---
// thread A
p = p3; // reads p3, writes p
// thread B
p3.reset(); // writes p3; undefined, simultaneous read/write

m_Res is not threadsafe ,because it simultaneous read/write,
you need boost::atomic_store/load function to protects it.

//--- Example 3 ---
// thread A
p = p3; // reads p3, writes p
// thread B
p3.reset(); // writes p3; undefined, simultaneous read/write
郁金香雨 2024-07-23 03:56:36

添加,你的类有一个循环引用条件; shared_ptr; m_Res 不能是 CResourceBase 的成员。 您可以使用 weak_ptr 代替。

Add, your class has a Cyclic-references condition; the shared_ptr<CResource> m_Res can't be a member of CResourceBase. You can use weak_ptr instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文