遍历具有危险指针的列表

我正在使用Hazard指针来实现C中的无锁链表。除了各种基本队列和堆栈之外,我找不到任何示例代码。 问题是我需要遍历列表,所以我的问题是,如果一旦分配了危险指针的值,我就可以改变它的值。 例如:

t←Top
while(true) {
    if t=null then
        return null
    *hp←t
    if Top!=t then
        continue
    ...
    t←(t→next) //after this instruction pointer t will be still protected?
}

最后,我根据原始文件结束实施我自己的危害指针(HP)版本。 我的问题的答案是否定的,t不再安全使用。 原因在于,HP的工作方式是* hp在将节点声明为危险指针时保护节点,所以当t移动到下一个节点时,HP机制会保护前一个节点。 在我可以安全使用它之前,我必须重新分配* hp的新值。

此外,在纸张的例子中,它并不明确,但是当您完成使用危险指针时,您必须将其释放。 这意味着,返回* hp到其原始状态(NULL)。 这样,如果另一个线程想要删除(退出)该节点,它将不会被视为正在使用。

在我上面的例子中,我必须在离开方法之前释放* hp 。 在循环内不需要,因为我覆盖了相同的* hp位置(* hp←t),所以前一个节点不再受保护。


当您仅遍历列表时,不需要危险指针。 当不同的线程正在读写同一个资源时(特别是,危险指针要​​克服ABA问题,当资源的值改变为某个值,然后回到其原始值,这使得注意到更改变得困难) 。 随着遍历,你只能阅读,因此不需要危险指针。

顺便说一下,在我看来, if Top=tif Top!=tif Top!=t必须更改,以便在没有危险时继续执行代码。 请注意, continue返回到循环的开始。 另外,你的整个代码应该在while(true)循环中。

您可以在这里阅读更多关于危险指针的信息http://www.drdobbs.com/lock-free-data-structures-with-hazard-po/184401890,或者只是通过Google搜索!

编辑你需要提供插入和删除功能的代码。 简而言之,你提到的那部分代码在执行t←(t→next)之后最终会成为一个无限循环,因为Top!= t将在之后保持为真。 你需要做的不是检查Top,而是检查它与之前捕获的值。 同样,这取决于你对其他方法的实现,但是你可能想要实现类似于Tim Harris算法,它使用两阶段删除(1标记和2释放节点)。 然后,当您遍历列表时,您还需要检查标记的节点。 还有一个双链表的实现,其中有一个find方法,您可以将其用作实现的基础,如图9中的http://www.research.ibm.com/people/m/michael/ieeetpds- 2004.pdf。 希望这可以帮助。

链接地址: http://www.djcxy.com/p/17707.html

上一篇: Traversing a list with hazard pointers

下一篇: Average Response times using PHP/MySQL