【问题标题】:How to implement double compare and swap in C/Linux?如何在 C/Linux 中实现双重比较和交换?
【发布时间】:2013-08-26 17:06:43
【问题描述】:

我正在阅读"Simple, fast, and practical non-blocking and blocking concurrent queue algorithms" 的论文,我意识到他们假设计算机原子地实现了以下伪代码:

CAS(Q->Tail,tail,<next.ptr,next.count+1>)

其中 Q->Tail 和 tail 是一个指针和一个包含指针和计数器的结构的实例。

我知道 gcc 为 c 中的单字比较和交换提供了几个内置插件。但是,是否可以从 c 中的单个比较和交换(使用 Linux)实现非阻塞原子双重比较和交换?这是实现参考论文伪代码的正确方法吗?

【问题讨论】:

  • 既然我不打算买报纸,那Tail到底是什么?真的是指针加上计数器吗?

标签: c queue nonblocking lock-free


【解决方案1】:

我不知道在两个不同的内存位置上工作的任何 CAS 操作。但是,该论文可能使用指针和计数器的结构作为解决方法,将这两个字段视为更大的类型,因此,原子地更改两者。

假设你有一个包含两个字段的结构,一个指针和一个计数器:指针大小为 4 字节,计数器大小为 4 字节;正确对齐而不填充到 8 字节的结构大小。假设您还有一个处理 8 字节值的 CAS 操作(例如指向 64 位整数的指针)。可以单独准备结构体的值,对结构体整体进行CAS操作,一次改变两个值。

【讨论】:

  • 注:我没有看论文,只是猜测。我可能是错的,也可能有其他我不知道的方法。
  • DCAS 对两个不同的操作数进行操作,但很少见。 DWCAS(doublewide) 对两个相邻的值进行操作,这相当于您对 CAS 所做的操作,其宽度足以容纳两个较小的值。
【解决方案2】:

Gcc 还提供了双字 CAS 的内置函数,可以使用 __sync_bool_compare_and_swap,如果 sizeof(*Q->Tail) == sizeof(tail) == sizeof(third_arg) == 8。 因此,如果您可以在执行 CAS 之前增加“next.count”,那么一切正常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-11
    • 2016-05-10
    • 2022-08-02
    相关资源
    最近更新 更多