我希望在读写器场景中使用std::shared_ptr。一个线程不断地接收新信息,并保持一个指向最新数据的智能指针。当需要运行我的慢速计算时,我会用一个智能指针指向所有数据,以确保我看到的是一致的数据。在下面的例子中,当我使用a和b时,我知道它们属于一起。
我不确定我是否应该在这里使用atomic_load和atomic_store?我不太在乎我在看哪个版本的Foo,只要它是一致的和有效的。
那么,我应该在智能指针上使用atomic吗?这样代码才能在两个不同的线程中工作?
谢谢,
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;
};
};
- shared_ptr::operator=默认情况下不是原子的
- shared_ptr不是TriviallyCopy,因此它不能是std::atomic的模板参数
因此,您必须以其他方式同步它们,例如通过std::mutex。
是的,对于std::shared_ptr
参数,必须使用memory
标头中重载的std::atomic_load()
和std::atomic_store()
。否则,代码中就会出现数据竞赛。(根据问题的标签,我假设您有一个兼容C++11的编译器。)
是的,必须以某种方式保护两个线程之间的任何通信。这种情况下的问题是std::shared_ptr<>::operator=
不能保证是原子的,因此如果两个线程都在访问它,则可能会调用未定义的行为