这个问题描述了什么是actor programming中的actors。什么是消息?如果您在消息中发送对象(假设对象存在于actor programming中),如何避免共享状态?
答:这个问题描述了在actor编程中,什么是actors。消息是指在actor之间传递的信息。如果您在消息中发送对象,可以通过复制对象并在接收方进行修改而避免共享状态。 +------+ 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 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
接收的消息必须同步运行,所有读/写操作都会相互干扰。因此,无需使用互斥锁。