Actor模型:我们能用Actor模型得到共享锁的语义吗



一个参与者一次处理一条消息并封装它不共享的状态,这一事实足以提供同步语义。因此,互斥(写锁定(得到了解决。然而,我们如何实现读写锁语义,即多个读取器可以并行工作,但读取器和写入器是互斥的?例如:并发哈希映射。

通过消息传递,为锁"建模"的参与者可以使用正确的权限处理写/读访问模式。其想法是,其他参与者向锁参与者发送获取锁的请求,然后等待回复。使用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。哈希映射可以保留在状态中。您可能有一些函数可以对状态hashmap进行操作。

最新更新