cas

(Требуется версия Workerman>=3.3.0)

bool \GlobalData\Client::cas(string $key, mixed $old_value, mixed $new_value)

Атомарная замена, заменяет $old_value на $new_value.
Значение может быть записано только в том случае, если после последнего считывания текущим клиентом значение по ключу не было изменено другими клиентами.

Параметры

$key

Ключ. (например, если $global->abc, то abc - это ключ)

$old_value

Старое значение

$new_value

Новое значение

Возвращаемое значение

Возвращает true в случае успешной замены, в противном случае возвращает false.

Пояснение:

При одновременной работе нескольких процессов с одной общей переменной иногда необходимо учитывать проблемы параллелизма.

Например, процессы A и B одновременно добавляют элемент в список пользователей.
При этом в текущий момент список пользователей для процессов A и B имеет значение $global->user_list = array(1,2,3).
Процесс A работает с переменной $global->user_list, добавляя пользователя 4.
Процесс B работает с переменной $global->user_list, добавляя пользователя 5.
Процесс A устанавливает переменную $global->user_list = array(1,2,3,4) успешно.
Процесс B устанавливает переменную $global->user_list = array(1,2,3,5) успешно.
При этом значение, установленное процессом B, перезаписывает значение, установленное процессом A, что приводит к потере данных.

В данном случае возникают проблемы параллелизма из-за того, что чтение и установка не являются атомарными операциями.
Для решения этой проблемы параллелизма можно использовать атомарный метод замены cas.
Метод cas перед изменением значения проверяет, не изменялось ли его значение другими процессами с помощью $old_value и возвращает false, если были изменения. В противном случае возвращает true.
Обратитесь к примеру ниже.

Примечание:
Некоторые общие данные могут быть перезаписаны параллельно без проблем, например, текущая максимальная ставка в системе аукционов, текущий запас определенного товара и т. д.

Пример

$global = new GlobalData\Client('127.0.0.1:2207');

// Инициализация списка
$global->user_list = array(1,2,3);

// Атомарно добавляем значение в user_list
do
{
    $old_value = $new_value = $global->user_list;
    $new_value[] = 4;
}
while(!$global->cas('user_list', $old_value, $new_value));

var_export($global->user_list);