【问题标题】:thread safety for objects stored in the shared pointer存储在共享指针中的对象的线程安全
【发布时间】:2012-08-19 13:17:42
【问题描述】:

我有一个boost::shared_ptr<Map>,这个映射正在被多个线程修改,我需要使用显式互斥锁还是线程通过共享指针修改映射的事实,我将获得某种隐式线程安全?

【问题讨论】:

  • 没有。 shared_ptr 绝对不会为线程安全做任何事情。它所做的只是为动态分配的对象提供引用计数语义。
  • 对您的问题的简短回答是“否”。 shared_ptr 提供的线程安全仅适用于指针本身。它没有做任何事情来保护对象本身。一旦你从 shared_ptr 结构中获得了一个指向底层对象的指针,你就不会再有魔法发生了。
  • @DavidSchwartz 我总是通过间接访问对象 shared_ptr 而不是通过原始指针。那会提供线程安全吗?
  • @Jimm:不。shared_ptr 所做的只是给你指向对象的指针。没有什么能阻止一个线程通过该指针修改对象,而另一个线程正在读取它。 shared_ptr 的线程安全只保护共享指针系统,而不保护底层对象。 (例如,如果两个线程同时丢弃指向同一个对象的智能指针,或者如果一个线程同时从智能指针获取常规指针,另一个线程丢弃指向同一个对象的智能指针,它可以确保完整性。等等。)

标签: c++ shared-ptr


【解决方案1】:

Did you even look at the docs?

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

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

编辑:看起来您是在询问指向的对象,而不是指针本身。在这种情况下,根本没有线程安全指标。为什么会有?

【讨论】:

  • 如果你正在读取的指针有任何可能发生变化,那么读取它是不安全的,比普通指针要少得多。常规指针是一个字,共享指针是指向对象的指针和指向计数的单独指针。因此,从它读取在任何架构上都不是天生的原子。因此,一个问题是您可以读取一个不匹配的值和一个计数器......另一个问题是,如果共享指针发生更改,则该对象可能会在读取它的过程中在另一个线程中被删除。引用计数的增量可能会损坏。
【解决方案2】:

shared_ptr 具有与内置类型相同级别的线程安全性。

您可以同时从多个线程执行读取 (const) 操作。

您还可以从多个线程同时对不同的shared_ptr 实例执行写操作(即使用可变操作,例如operator=reset)。这包括这些实例共享相同引用计数的情况(因为shared_ptr 为引用计数器提供原子增量/减量)。

如果您需要任何其他类型的访问权限,则需要对其进行同步,否则您将获得未定义的行为。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-02
    • 1970-01-01
    • 2018-12-05
    • 1970-01-01
    相关资源
    最近更新 更多