Многие из 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 принимают два указателя и значение вместо того, что кажется более обычным указателем и двумя значениями?
Способ 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
вам даже нужно выполнять другую загрузку каждый раз, когда происходит сбой обмена.
Я не понимаю, почему у вас не было бы и того и другого. В моем случае C ++ версия менее полезна. Я хочу подождать, пока переменная не получит какое-либо значение, а затем установить новое значение.
С помощью GCC:
while (!__sync_bool_compare_and_swap(&value, expected, desired)) { }
С С ++ 11:
auto tmp = expected;
while (!value.compare_exchange_weak(tmp,desired))
{
tmp = expected;
}