Модель актера: Можем ли мы получить семантику разделяемой блокировки с моделью актера?

Тот факт, что субъект обрабатывает одно сообщение за раз и инкапсулирует состояние, которое он не разделяет, достаточен для обеспечения семантики синхронизации. Таким образом, взаимное исключение (запись-блокировка) решено. Однако как нам реализовать семантику блокировки чтения-записи, когда несколько читателей могут работать параллельно, а читатели и писатели являются взаимоисключающими? Например: одновременный HashMap.

2 ответа

При передаче сообщений субъект, который "моделирует" блокировку, может обрабатывать режимы доступа на запись / чтение с правильными разрешениями. Идея состоит в том, что другие субъекты отправляют запросы на захват блокировки субъекту блокировки и ждут ответа. Используя Erlang, состояние субъекта блокировки может быть чем-то вроде #{writer := boolean(), readers := integer()} и цикл управления что-то вроде:

%% A writer holds the lock:
loop(#{writer := true, readers := 0}) ->
  receive
    unlock_write -> loop(#{writer => false, readers => 0})
  end;
%% One or more readers hold the lock:
loop(#{writer := false, readers := N}) when N > 0 ->
  receive
    {lock_read, Who} -> Who ! lock_granted, loop(#{writer => false, readers => N + 1});
    unlock_read -> loop(#{writer => false, readers => N - 1})
  end;
%% No writer or readers hold the lock:
loop(#{writer := false, readers := 0}) ->
  receive
    {lock_read, Who} -> Who ! lock_granted, loop(#{writer => false, readers => 1});
    {lock_write, Who} -> Who ! lock_granted, loop(#{writer => true, readers => 0})
  end.

Обратите внимание, что в каждом состоянии единственными сообщениями, которые могут быть обработаны, являются те, которые "разрешены" этим состоянием (например, когда блокировщик удерживает блокировку только unlock_write сообщение можно обработать и изменить состояние).

В Erlang вы можете сделать это несколькими способами. Наиболее очевидным способом является использование таблицы ETS. Все записи ets являются атомарными (даже если они содержат несколько записей). Что может быть еще лучше, это настроить защищенную таблицу ets, в которой 1 процесс может писать, но все процессы могут читать.

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

Используйте gen_server. Хеш-карта может быть сохранена в состоянии. У вас могут быть функции для работы с состоянием, хэш-карта.

Другие вопросы по тегам