9

我怎样才能实现这个无锁队列伪代码C

ENQUEUE(x)
    q ← new record
    q^.value ← x
    q^.next ← NULL
    repeat
        p ← tail
        succ ← COMPARE&SWAP(p^.next, NULL, q)
        if succ ≠ TRUE
            COMPARE&SWAP(tail, p, p^.next)
    until succ = TRUE
    COMPARE&SWAP(tail,p,q)
end

DEQUEUE()
    repeat
        p ← head
        if p^.next = NULL
            error queue empty
    until COMPARE&SWAP(head, p, p^.next)
    return p^.next^.value
end

如何使用内置函数进行原子内存访问

__sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...)

我目前有

typedef struct queueelem {
    queuedata_t data;
    struct queueelem *next;
} queueelem_t;

typedef struct queue {
    int capacity;
    int size;
    queueelem_t *head;
    queueelem_t *tail;
} queue_t;

queue_t *
queue_init(int capacity)
{
    queue_t *q = (queue_t *) malloc(sizeof(queue_t));
    q->head = q->tail = NULL;
    q->size = 0;
    q->capacity = capacity;
    return q;
}
4

5 回答 5

15

https://www.liblfds.org/

公共领域,无许可证,C 语言无锁算法的可移植实现。

为 Windows 和 Linux 开箱即用。

在 Linux 上使用 GCC,因此使用内在函数(好吧,除了 128 位 CAS,没有内在函数 - 为此使用内联汇编)。

包含 M&S 队列。看看源代码,看看它是如何完成的。

于 2011-05-26T15:01:29.897 回答
5

如果您的目标是生产代码,请不要这样做;使用锁。

您之前的问题中,您已经获得了足够的信息来解释原因。由于著名的 ABA 问题,在没有垃圾收集器的情况下,即使是简单的数据结构(例如队列和堆栈)的正确无锁实现也是棘手和复杂的。不幸的是,一些研究论文无论出于何种原因都没有考虑到 ABA。您的伪代码似乎取自其中一篇论文。如果将其转换为 C 并为节点使用堆分配内存,则在实际代码中使用时会导致不确定的错误。

如果您这样做是为了获得经验,那么不要指望 SO 研究员会为您解决它。您必须阅读所有引用的材料等等,确保您真正了解无锁算法(如 ABA)的所有细微差别,研究旨在解决该问题的各种技术,研究现有的无锁实现等。

最后,将给定的伪代码翻译成 C 的指导很少:

q^.value ← x 手段q_elem->data = x;
repeat ... until COMPARE&SWAP(head, p, p^.next)相当于do {...} while (!__sync_bool_compare_and_swap(q_obj->head, q_elem, q_elem->next);

其中q_obj是类型实例queue_t(即队列),q_elem是类型实例queueelem_t(即队列节点)。

于 2011-05-23T06:39:39.160 回答
0

虽然不完全是 C,但请查看建议的 Boost.Lockfree库。内部非常容易理解,可以移植到 C,或者相反,您可以将 Boost.Lockfree 包装在 C API 中并使用它。

同样,Boostcon 2010有很多关于无锁编程和 STM 的讨论,如果您对此主题感兴趣,值得一看。我找不到视频的链接,但英特尔、IBM 和 AMD 的演讲值得一看,因为他们正在处理 CPU 级别的 STM。

于 2011-05-23T05:03:28.863 回答
0

听起来你想要的叫做 MCS 队列锁(虽然名字很假,但它确实是无锁的,只是不是无等待的),这里有一些很好的伪代码:http://www.cs.rochester .edu/research/synchronization/pseudocode/ss.html#mcs

于 2011-05-23T05:30:36.260 回答
-2

我使用 C 编写了一个最小化无锁队列实现。

lfq _

它支持许多生产者,许多消费者。

于 2017-02-22T01:17:06.487 回答