我正在尝试提供一种更新对象的线程安全方法。我已经看过一些关于它的帖子,但没有任何内容可以100%回答我的问题。
我想要做的是维护一个名为'm_First'的指针来指向我的数据。如果有人调用get,我会依赖指针,返回对它指向的对象的引用。
如果有人调用set,传入指向新对象的指针,我们将该指针添加到列表中并更新m_First以指向新对象。
我将对象存储在向量中,这样我们就可以在完成后清理内存。
目前我定义了这些成员:
std::vector<MyObject*> m_List;
const MyObject* m_First;
首先是这样的初始化。 m_First = m_List.back();
我想允许多个线程读取m_First,而多个线程也写入m_First。
我的课有两种方法
MyObject& getMyObject() {return *m_First;}
void setMyObject(MyObject* newObj) {
m_List.push_back(newObj); // add to list so we can later cleanup mem
do {
Node* oldHead = m_First;
} while (!__sync_bool_compare_and_swap(m_First, *oldHead, *newObj));
}
我想知道的是,在get方法线程安全中返回* m_First。即我可以安全地取消引用它并返回对象的引用,而另一个线程正在尝试更新m_First,或者我是否需要使用某种原子方法来读取m_First。
任何建议/帮助都将不胜感激。
答案 0 :(得分:0)
为了确保从内存中读取值而不是从寄存器中读取值,您需要进行原子读取。
有不同的方法来实现这一目标。在某些系统上,通过类似*(const volatile MyObject*)p
的易失性指针读取对齐的字大小值将起作用。但由于您已经在使用内置原子操作,因此您可以使用__sync_add_and_fetch
之类的内容添加0。
答案 1 :(得分:0)
我想允许多个线程读取m_First,而多个线程也写入m_First。
多个线程如何写入m_First
?如果它是通过setMyObject
那么他们将同时修改m_List
向量,这将是一个数据竞争,几乎肯定会破坏向量。