【问题标题】:Do I need to use std::atomic_ when having one reader and one writer thread当有一个阅读器和一个编写器线程时,我是否需要使用 std::atomic_
【发布时间】:2016-07-24 14:18:17
【问题描述】:

我希望在读写器场景中使用 std::shared_ptr。一个线程不断接收新信息并保持一个指向最新数据的智能指针。当需要运行我的慢速计算时,我将智能指针指向所有数据,以确保我正在查看一致的数据。在下面的示例中,当我使用 a 和 b 时,我知道它们属于一起。

我不确定我是否应该在这里使用 atomic_load 和 atomic_store?只要它是一致且有效的,我并不关心我正在查看哪个版本的 Foo。

那么我应该在我的智能指针上使用 atomic 以使这段代码在两个不同的线程中工作吗?

谢谢,

保罗

#include <iostream>
#include <memory>


class Foo{
public:
    int a;
    int b;
};

class MyClass{
public:
  std::shared_ptr <Foo> lastValue;
  void realTimeUpdate (Foo* latest) { //takes ownership of Foo
      lastValue=std::shared_ptr <Foo> (latest); //Is this OK to do without using std::atomic_?
  };

  void doSlowCalcFromAnotherThread () {
      //take a reference to all input data
      std::shared_ptr <Foo> stableValue=lastValue; //Is this OK to do without using std::atomic_
      //display a and b guaranteed that they come from the same message
      std::cout<<"a: "<<stableValue->a<<std::endl;
      std::cout<<"b: "<<stableValue->b<<std::endl;
  };
};

【问题讨论】:

  • 您可能应该使用std::mutex 来保护对指针的访问,并且收工。 std::shared_ptr 的赋值不是原子的。

标签: multithreading c++11 shared-ptr stdatomic


【解决方案1】:
  1. shared_ptr::operator= 默认不是原子的。
  2. shared_ptr 不是 TriviallyCopyable,因此它不能是 std::atomic 的模板参数。

所以你必须以其他方式同步它们,例如通过 std::mutex。

【讨论】:

    【解决方案2】:

    是的,您必须在 memory 标头中为 std::shared_ptr 参数使用重载的 std::atomic_load()std::atomic_store()。否则,您将在代码中出现数据竞争。 (根据问题的标签,我假设您有一个符合 C++11 的编译器。)

    【讨论】:

    • 谢谢。不幸的是,gcc 4.9.2 似乎没有实现 std::atomic_load 并为 std::shared_ptr 存储,所以我必须坚持使用互斥锁。 C++17 可能包含一个 std::atomic_shared_ptr 应该在这些情况下工作,但在可用之前需要一段时间。
    【解决方案3】:

    是的,两个线程之间的任何通信都必须以某种方式进行保护。这种情况下的问题是 std::shared_ptr&lt;&gt;::operator= 不能保证是原子的,因此如果两个线程都在访问它,则可能会调用未定义的行为

    【讨论】:

    猜你喜欢
    • 2015-04-19
    • 1970-01-01
    • 2013-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-04
    • 1970-01-01
    相关资源
    最近更新 更多