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