TL; DR: поскольку, если ожидаемый параметр был ссылкой const
, compare_exchange
не сможет изменить его при сбое обмена.
Вы предоставляете оба параметра ожидаемое и желаемое значение до compare_exchange
.Он изменяет ваше ожидаемое значение, если он находит значение, отличное от того, которое вы указали.В этом случае ожидаемое значение не заменяется указанным вами желаемым значением (т. Е. Оно не удалось обменять, поэтому вы можете попытаться обменять значение снова).
Обычно вы хотите использоватьэти функции в цикле, по этой причине изменение ожидаемого значения, которое вы указали, имеет смысл, поскольку предоставляет вам обновленную версию ожидаемого значения.
Рассмотрим следующее атомное значение:
std::atomic<int> a = 7;
, и вы хотите удвоить значение a
:
int expected = a.load(), desired;
do {
desired = 2 * expected;
} while (!a.compare_exchange_weak(expected, desired));
В приведенном выше коде, если a
перед обменом изменяется другим потоком, expected
обновляется на compare_exchange
значением a
в момент попытки обмена (т. е. в момент сбоя).
В противном случае, если expected
не был изменен на compare_exchange
в случае сбоя, вам нужно будет загрузить значение a
на каждой итерации цикла, чтобы обновить expected
:
int expected, desired;
do {
expected = a.load(); // <-- load on each iteration
desired = 2 * expected;
} while (!a.compare_exchange_weak(expected, desired));