使用sync_val_compare_and_swap锁定空闲列表

时间:2012-07-13 16:33:10

标签: c++ lock-free compare-and-swap

我正在尝试提供一种更新对象的线程安全方法。我已经看过一些关于它的帖子,但没有任何内容可以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。

任何建议/帮助都将不胜感激。

2 个答案:

答案 0 :(得分:0)

为了确保从内存中读取值而不是从寄存器中读取值,您需要进行原子读取。

有不同的方法来实现这一目标。在某些系统上,通过类似*(const volatile MyObject*)p的易失性指针读取对齐的字大小值将起作用。但由于您已经在使用内置原子操作,因此您可以使用__sync_add_and_fetch之类的内容添加0。

答案 1 :(得分:0)

  

我想允许多个线程读取m_First,而多个线程也写入m_First。

多个线程如何写入m_First?如果它是通过setMyObject那么他们将同时修改m_List向量,这将是一个数据竞争,几乎肯定会破坏向量。