Actor模型:我们可以获取与Actor模型共享锁的语义吗?

时间:2018-11-16 19:15:49

标签: erlang akka actor otp actor-model

actor一次处理一个消息并封装不共享的状态的事实足以提供同步语义。因此,互斥(写锁定)已得到处理。但是,我们如何实现读写锁定语义,在这种语义下,多个读者可以并行工作,但读者和作家却是互斥的?例如:并发HashMap。

4 个答案:

答案 0 :(得分:3)

通过消息传递,对锁进行“建模”的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消息并更改状态)

答案 1 :(得分:0)

在Erlang中,您可以通过几种方式来执行此操作。最明显的方法是使用ETS表。所有ets的写入都是原子的(即使它们包含多个记录)甚至更好的方法是设置一个受保护的ets表,其中1个进程可以写入,但所有进程都可以读取。

答案 2 :(得分:-1)

参与者模型解决方案中的

互上下文通过队列概念及其避免锁定机制来处理反压力。  如果您想要分片内存,请使用ets等其他内容。

答案 3 :(得分:-1)

使用gen_server。哈希图可以保留在状态中。您可能具有对状态哈希表进行操作的功能。