如果我们认为演员是人,那么消息就像......消息.
说一个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必须同步运行,因此所有读/写操作都会相互干扰.因此,没有必要混淆互斥量.