14

C++11 CAS 操作の多く (例: , atomic_compare_exchange_weak)atomic_compare_exchange_strongは、次のように 2 つのポインターと 1 つの値を取ります。

bool atomic_compare_exchange(T* pointer, T* expected,       // pseudodeclaration!
                             T desired);

対照的に、Microsoft、gcc、Intel の CAS 操作はすべて、1 つのポインターと 2 つの値を取ります。

long InterlockedCompareExchange(long* pointer, long desired,       // Microsoft
                                long expected);

int __sync_bool_compare_and_swap (T* pointer, T expected,          // gcc and
                                  T desired);                      // Intel

C++11 の CAS 関数は、従来の 1 つのポインターと 2 つの値のように見えるものではなく、2 つのポインターと 1 つの値を取るのはなぜですか?

4

2 に答える 2

23

C++11 の方が便利です。交換が失敗した場合は*expected、新しい現在の値に更新されます。これにより、ループ内で関数を簡単に使用できます。

T value = x.load();
T newvalue = frob(value);

while (!atomic_compare_exchange(&x, &value, newvalue))
{
    newvalue = frob(value);
}

Microsoft の署名では、操作が成功したかどうかのテストはより面倒であり、GCC の__sync_typeバージョンについても同様です。GCC__sync_boolでは、交換が失敗するたびに別のロードを実行する必要さえあります。

于 2013-04-16T17:57:04.460 に答える