原子比较(不等于)和交换

时间:2012-10-05 23:02:51

标签: c multithreading gcc compare-and-swap

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

2 个答案:

答案 0 :(得分:4)

这个怎么样:

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()是票证。由于某种原因,它需要一个指向'expected'参数的指针,因此您必须将上面的代码修改为

  

if(atomic_compare_exchange_weak(ptr_to_shared_variable,& snapshot_value,new_value))...

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

答案 1 :(得分:1)

这取决于您的架构,但通常无法在C中执行此操作。

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

至少在x86上,如果值不匹配,则不会仅执行此加载。还不清楚你为什么要做那样的事情。也许另一种架构可以支持这样的东西,但这将取决于架构,而不是可以通过便携方式在C中完成的。