繁体   English   中英

有没有办法让 std::atomic 的 compare_exchange_strong 方法在不等式上进行交换?

[英]Is there a way to have a version of std::atomic's compare_exchange_strong method that exchanges on inequality?

我有一个原子类型,我需要将它与一个值进行原子比较,如果两个值不相等,则交换原子的值。

换句话说, compare_exchange_strong本质上是原子地执行此操作:

if (atomic_value == expected)
    atomic_value = desired;

...我正在寻找一种方法来做到这一点:

if (atomic_value != expected)
    atomic_value = desired;

(是的,我知道compare_exchange_strong使用按位相等进行比较,而不是==运算符。而且我知道比较失败时会分配expected的值。这仅用于说明目的。在我的用例中,我不需要无论比较结果如何,都是原子的。)

有什么方法可以做到这一点而不必依赖使用锁而不是std::atomic

auto observed = atomic_value.load();
for (;;)
{
    if (observed == expected){
       break; // no exchange
    }
    if (atomic_value.compare_exchange_weak(observed, desired)) { 
       break; // successfully exchanged observed with desired
    }
}

当然,它在硬件具有 LL/SC 的架构上不是最理想的,因为 C++ 没有暴露它。 LL/SC 可以有任意条件。

只需使用通常与比较和交换一起使用的循环,但不要循环直到(新)预期值匹配,而是循环直到它匹配(并且存储发生)或者它等于您的值!= expected条件,因为在这种情况下你不需要做任何事情。 (显然不要将初始值设为“除非”值,以免第一次“成功”。)

你可以使用这样的东西:

#include <atomic>
#include <random>

std::atomic<int> atomVal;

int store_if_not_equal(int desired)
{
    while (true)    // or maxloop....
    {
        int expected = desired;

        if (atomVal.compare_exchange_strong(expected, desired))
        {
            // values matched - do nothing
            return 0;
        }
        else
        {
            //expected now contains the "current value"
            // another thread could have sneaked in and changed it,
            // so only replace it if it still matches
            if (atomVal.compare_exchange_strong(expected, desired))
            {
                // success
                return 1;
            }
        }

    // if we arrive here, retry
    }
}

int main()
{
    atomVal.store(rand());
    return store_if_not_equal(2);
}

演示: https://godbolt.org/z/qWTP7canf

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM