演员模型中的消息是什么?

3

这个问题描述了什么是actor programming中的actors。什么是消息?如果您在消息中发送对象(假设对象存在于actor programming中),如何避免共享状态?

答:这个问题描述了在actor编程中,什么是actors。消息是指在actor之间传递的信息。如果您在消息中发送对象,可以通过复制对象并在接收方进行修改而避免共享状态。
1个回答

9
如果我们认为演员是人,那么消息就像...消息。
假设老板想要对一组数字列表a进行平方根运算,并且不想亲自计算。他可以雇用一些工人,老板将知道他们的电话号码。
所以老板会给每个工人发送短信,告诉他们“找到a_i的平方根;完成后在555-1234回复我。” 这个指令就是一条消息。老板随后会等待工人完成任务。
 +------+  sqrt(i=0, a_i=9)         +------------+
 | Boss | ------------------------> | Worker 0   |
 +------+                           +------------+
       |   sqrt(i=1, a_i=16)        +------------+
       ‘--------------------------> | Worker 1   |
                                    +------------+
                                       ....

在工人完成计算后,他们会通过短信将结果发送回老板并汇报。这也是通过消息传递来完成的。
 +------+   set_result(i=0, val=3)  +------------+
 | Boss | <------------------------ | Worker 0   |
 +------+                           +------------+
       ^  set_result(i=1, val=4)    +------------+--------------------------- | Worker 1   |
                                    +------------+
                                       ....

这听起来像面向对象编程,但是发送或接收消息时没有顺序 - 它们是异步传递的。 (但是,在actor本身内部,消息是同步接收和排队的。)
在代码中编写时,可能会像这样:
actor Boss:
   receive('run'):
     worker_addrs = spawn_many(SqrtWorker, len(a))  # hire workers.
     for i, addr in enumerate(worker_addrs): 
        send(addr, 'sqrt', reply_addr=self, i=i, a_i=a[i])

   receive('set_value', i, val):
     a[i] = val

actor SqrtWorker:
   receive('sqrt', reply_addr, i, a_i):
     send(reply_addr, 'set_value', i, sqrt(a_i))
     quit()

“共享状态问题”不存在,因为状态不可能在没有复制的情况下被共享。在上面的例子中,列表 a 的元素被复制到每个工作线程中。实际上,只有老板知道 a 的存在——这是一个“本地状态”。

那么,如果我们真的想让 a 被共享怎么办?在 Actor 模型中,我们将它们转换成一个新的 actor,并将该 actor 的电话号码发送给工人。

 +------+  sqrt(i=0, a_phoneNum=555-1111)  +----------+
 | Boss | -------------------------------> | Worker 0 |
 +------+                                  +----------+

             +---+
             | a |
             +---+

工人随后向清单上的演员询问所需信息(这是可能的,因为老板已经将 a 的电话号码提供给了工人)。
 +------+                                 +----------+
 | Boss |                                 | Worker 0 |
 +------+                                 +----------+
                                               |
             +---+                             |
             | a | <---------------------------’
             +---+             get(i=0)

过了一段时间,列表回复如下...

 +------+                                 +----------+
 | Boss |                                 | Worker 0 |
 +------+                                 +----------+
                                               ^
             +---+       list_val(i=0, val=9)  |
             | a | ----------------------------’
             +---+

在收到 list_val 消息后,工作者可以计算平方根。

 +------+     set_result(i=0, val=3)      +----------+
 | Boss | <------------------------------ | Worker 0 |
 +------+                                 +----------+

             +---+
             | a |
             +---+

老板终于更新了共享状态。
 +------+                                 +----------+
 | Boss |                                 | Worker 0 |
 +------+                                 +----------+
    | set(i=0, val=3)                
    |        +---+ ------> | a | 
             +---+ 

像这样访问共享状态会有问题吗?不会有问题,因为由a接收的消息必须同步运行,所有读/写操作都会相互干扰。因此,无需使用互斥锁。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接