代码之家  ›  专栏  ›  技术社区  ›  Andrew Grimm Alex Wayne

演员节目中的信息是什么?

  •  3
  • Andrew Grimm Alex Wayne  · 技术社区  · 15 年前

    This question 描述演员编程中的演员。什么是信息?如果在消息中发送对象(假设对象存在于actor编程中),如何避免共享状态?

    1 回复  |  直到 15 年前
        1
  •  9
  •   kennytm    15 年前

    如果我们认为演员是人,那么信息就像…信息。

    假设一个老板想要一个数字列表的平方根 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 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()
    

    没有“共享状态问题”,因为没有复制就无法共享状态。在上面的示例中,list的元素 复制的 给每个工人。事实上,只有老板知道 这是一个 局部状态 .

    如果我们真的想 共享?在演员模型中,我们将把他们转换成一个新的演员,并将这个演员的电话号码发送给工人。

     +------+  sqrt(i=0, a_phoneNum=555-1111)  +----------+
     | Boss | -------------------------------> | Worker 0 |
     +------+                                  +----------+
    
                 +---+
                 | 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 | 
                 +---+ 
    

    访问这样的共享状态会有什么问题吗?由于收到的消息 必须同步运行,所有读/写操作都会相互干扰。因此,没有必要乱用互斥体。

    推荐文章