Reputation: 148
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
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
Reputation: 11940
So you have to synchronize 'em in some other way, e.g. via std::mutex.
Upvotes: 2
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