【问题标题】:atomic compare(not equal) and swap原子比较(不等于)和交换
【发布时间】:2012-10-05 23:02:51
【问题描述】:

我想使用原子比较和交换,但不是等于,我只想在内存位置不等于旧值时进行交换。 C语言可以吗?

【问题讨论】:

    标签: c multithreading gcc compare-and-swap


    【解决方案1】:

    这个怎么样:

    void compare_and_swap_if_not_equal(word_t const required_non_value, word_t const new_value, word_t* ptr_to_shared_variable) { 
        for (;;) {
            word_t const snapshot_value = *ptr_to_shared_variable;
            if (required_non_value == snapshot_value) {
                break;
                // or (sleep and) 'continue;', if you want to wait for the stored value to be different 
                // -- but you might of course miss a transient change to a different state and back.
            } else { 
                if (compare_and_swap_if_equal(ptr_to_shared_variable, snapshot_value, new_value)) {
                    // we know the stored value was different; if this 'theory' still matches reality: swap! done!
                    break;
                }
            }
        }
    }
    

    未经测试。未编译。使用'const'是因为我喜欢这样:)。 'word_t' 是一个类型占位符,我不知道真正的类型应该是什么。而且我不知道在 stdatomic.h 中如何调用“compare_and_swap_if_equal”。

    (添加) atomic_compare_exchange_weak() 是票。出于某种原因,它需要一个指向“预期”参数的指针,因此您必须将上面的代码修改为

    如果 (atomic_compare_exchange_weak(ptr_to_shared_variable, &snapshot_value, new_value)) ...

    “弱”版本应该在上面的代码中工作;虚假地返回“false”只会在循环中增加另一个行程。仍未编译,未经测试;不要在家里依赖这个代码。

    【讨论】:

    • 如果指针总是在 snapshot_value 和原子 cas 之间变化怎么办?似乎循环永远不会结束。此外,在获取指针之前我们不需要内存屏障吗? (原子 cas 暗示它)
    • @IgorR。回复:'如果指针总是在获取快照值和原子 cas 之间发生变化怎么办?':是的,我认为这在真正不公平的系统上是可能的。超时或重试计数器可能是一个选项。有人可能想知道那将是一种什么样的系统和工作,以及为什么作者和读者不能更好地合作:)。另外,我想这也会发生在 CAS 'if equal' 的典型应用中,甚至更是如此,因为实际工作是在初始 fetch 和 CAS 之间完成的。
    • @IgorR。回复:'此外,在获取指针之前我们不需要内存屏障吗? (原子 cas 暗示)' 嗯,没想到这种事情……只有一个非局部变量受到影响,所以我不认为这里有任何这种排序问题,对吧?
    【解决方案2】:

    这取决于你的架构,但一般来说,在 C 中是不可能做到这一点的。

    通常,比较和交换是通过从内存中的某个位置自动加载的指令实现的,如果内存中的位置与您指定的某个现有值匹配,则将值存储到该位置。

    至少在 x86 上没有规定仅在值不匹配时才执行此加载。也不清楚你为什么想做这样的事情。也许另一种架构会支持这样的东西,但这将取决于架构,而不是可以在 C 中以可移植方式完成的事情。

    【讨论】:

    • 现代 x86 处理器中没有 cmov 指令吗?它是否符合所需的配置文件?
    • 我认为这行不通,因为在执行 cmov 之前,您需要一条指令来设置条件代码。因此,在检查条件代码和执行 cmov 之间的时间内,另一个处理器可能会更改您尝试写入的内存中的值。
    • 我明白了。感谢您的解释! =)
    • @JanitoVaqueiroFerreiraFilho 在 x86 上的 xchg 指令正是 OP 想要的,无条件的原子交换。
    猜你喜欢
    • 2021-03-09
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 2010-12-03
    • 2011-10-29
    • 2013-08-30
    • 1970-01-01
    • 2012-03-10
    相关资源
    最近更新 更多