演员编程中的消息是什么?

And*_*imm 3 message actor

这个问题描述了演员编程中的演员.什么是消息?如果在消息中发送对象(假设在actor编程中存在对象),如何避免共享状态?

ken*_*ytm 9

如果我们认为演员是人,那么消息就像......消息.

说一个Boss想要一个数字列表的平方根a,并且不想做所有计算himeself.他可以聘请一些工人,老板会知道他们的电话号码.

所以老板会给每个工人发短信,并告诉他们"找到平方根a_i;在你做完之后回复我555-1234".该指令是一条消息.然后Boss将等待工人完成.

 +------+  sqrt(i=0, a_i=9)         +------------+
 | Boss | ------------------------> | Worker 0   |
 +------+                           +------------+
       |   sqrt(i=1, a_i=16)        +------------+
       ‘--------------------------> | Worker 1   |
                                    +------------+
                                       ....
Run Code Online (Sandbox Code Playgroud)

在工人完成计算后,他们将向Boss发回短信并报告结果.这也是在消息传递中完成的.

 +------+   set_result(i=0, val=3)  +------------+
 | Boss | <------------------------ | Worker 0   |
 +------+                           +------------+
       ^  set_result(i=1, val=4)    +------------+
       ‘--------------------------- | Worker 1   |
                                    +------------+
                                       ....
Run Code Online (Sandbox Code Playgroud)

这听起来像面向对象的编程,但是当发送或接收消息时没有顺序 - 它们是异步传递的.(但是,在演员本身内,消息被同步接收和排队.)

用代码编写时,可能就像

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()
Run Code Online (Sandbox Code Playgroud)

没有"共享状态问题",因为没有复制就无法共享状态.在上面的示例中,list的元素a被复制到每个worker.事实上,只有Boss知道存在a- 这是一个本地国家.

现在如果我们真的想a分享呢?在actor模型中,我们将它们转换为新的actor,并将此actor的Phone号发送给Worker.

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

             +---+
             | a |
             +---+
Run Code Online (Sandbox Code Playgroud)

然后,工作人员向列表演员询问所需信息(这可能是因为Boss已将电话号码提供a给工人.)

 +------+                                 +----------+
 | Boss |                                 | Worker 0 |
 +------+                                 +----------+
                                               |
             +---+                             |
             | a | <---------------------------’
             +---+             get(i=0)
Run Code Online (Sandbox Code Playgroud)

一段时间后,清单回复......

 +------+                                 +----------+
 | Boss |                                 | Worker 0 |
 +------+                                 +----------+
                                               ^
             +---+       list_val(i=0, val=9)  |
             | a | ----------------------------’
             +---+
Run Code Online (Sandbox Code Playgroud)

然后工人可以在收到消息后计算平方根list_val.

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

             +---+
             | a |
             +---+
Run Code Online (Sandbox Code Playgroud)

Boss最终更新了共享状态

 +------+                                 +----------+
 | Boss |                                 | Worker 0 |
 +------+                                 +----------+
    | set(i=0, val=3)                
    |        +---+ 
    ‘------> | a | 
             +---+ 
Run Code Online (Sandbox Code Playgroud)

这样访问共享状态会有任何问题吗?否 - 由于收到的消息a必须同步运行,因此所有读/写操作都会相互干扰.因此,没有必要混淆互斥量.