Paul Beerkens
Paul Beerkens

Reputation: 148

Do I need to use std::atomic_ when having one reader and one writer thread

I am looking to use std::shared_ptr in a reader/writer scenario. One thread constantly receives new information and keeps a smart pointer to the latest data. When the time comes to run my slow calc I take a smart pointer to all the data to ensure that I am looking at consistent data. In the example below when I use a and then b I know that they belong together.

I am not sure if I should use atomic_load and atomic_store here? I don't care to much which version of Foo I am looking at as long as it is consistent and valid.

So should I use atomic here on my smart pointers in order for this code to work from two different threads?

Thanks,

Paul

#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;
  };
};

Upvotes: 4

Views: 96

Answers (3)

Daniel Langr
Daniel Langr

Reputation: 23497

Yes, you have to use std::atomic_load() and std::atomic_store() overloaded in the memory header for std::shared_ptr arguments. Otherwise, you would have a data race in the code. (I assume that you have a C++11 compliant compiler according the question's tags.)

Upvotes: 2

bipll
bipll

Reputation: 11940

  1. shared_ptr::operator= is not atomic by default.
  2. shared_ptr is not TriviallyCopyable, so it cannot be template parameter to std::atomic.

So you have to synchronize 'em in some other way, e.g. via std::mutex.

Upvotes: 2

kmdreko
kmdreko

Reputation: 60022

Yes, any communication between two threads must be protected in some manner. The issue in this case is that std::shared_ptr<>::operator= is not guaranteed to be atomic and thus may invoke undefined behavior if both threads are accessing it

Upvotes: 1

Related Questions