Почему C ++ 11 CAS-операции принимают два параметра указателя?

Многие из C ++ 11 операций CAS (например, atomic_compare_exchange_weak, atomic_compare_exchange_strong) взять два указателя и значение, например, так:

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

Напротив, операции CAS от Microsoft, gcc и Intel имеют один указатель и два значения:

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 принимают два указателя и значение вместо того, что кажется более обычным указателем и двумя значениями?

12

Решение

Способ 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вам даже нужно выполнять другую загрузку каждый раз, когда происходит сбой обмена.

21

Другие решения

Я не понимаю, почему у вас не было бы и того и другого. В моем случае C ++ версия менее полезна. Я хочу подождать, пока переменная не получит какое-либо значение, а затем установить новое значение.

С помощью GCC:

while (!__sync_bool_compare_and_swap(&value, expected, desired)) { }

С С ++ 11:

auto tmp = expected;
while (!value.compare_exchange_weak(tmp,desired))
{
tmp = expected;
}
3

По вопросам рекламы [email protected]