This question描述了演员编程中的演员。什么是消息?如果在消息中发送对象(假设在actor编程中存在对象),如何避免共享状态?
答案 0 :(得分:9)
如果我们认为演员是人,那么消息就像......消息。
说老板想要对数字列表a
的平方根进行平方,并且不想做所有的计算。他可以雇佣一些工人,老板会知道他们的电话号码。
所以老板会给每个工人发短信,告诉他们“找到a_i
的平方根;在你做完之后回复我555-1234。”此说明是消息。然后Boss将等待工人完成。
+------+ sqrt(i=0, a_i=9) +------------+
| Boss | ------------------------> | Worker 0 |
+------+ +------------+
| sqrt(i=1, a_i=16) +------------+
‘--------------------------> | Worker 1 |
+------------+
....
在工人完成计算后,他们将发送短信回到Boss并报告结果。这也是在消息传递中完成的。
+------+ set_result(i=0, val=3) +------------+
| Boss | <------------------------ | Worker 0 |
+------+ +------------+
^ set_result(i=1, val=4) +------------+
‘--------------------------- | Worker 1 |
+------------+
....
这听起来像面向对象的编程,但是在发送或接收消息时没有顺序 - 它们以异步方式传递。 (但是,在演员本身内,会同时接收和排队消息。)
用代码编写时,可能就像
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
的元素被复制到每个工作者。事实上,只有Boss知道a
的存在 - 这是本地状态。
现在如果我们真的希望共享a
怎么办?在演员模型中,我们将它们转换为新演员,并将此演员的电话号码发送给工人。
+------+ sqrt(i=0, a_phoneNum=555-1111) +----------+
| Boss | -------------------------------> | Worker 0 |
+------+ +----------+
+---+
| a |
+---+
然后,工作人员向列表演员询问所需信息(这是可能的,因为Boss已将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最终更新了共享状态
+------+ +----------+
| Boss | | Worker 0 |
+------+ +----------+
| set(i=0, val=3)
| +---+
‘------> | a |
+---+
访问这样的共享状态会有任何问题吗?否 - 由于a
收到的消息必须同步运行,因此所有读/写操作都会相互干扰。因此,没有必要混淆互斥量。