【问题标题】:How do I have scala actors reporting task completion?我如何让 scala 演员报告任务完成?
【发布时间】:2012-03-30 11:51:32
【问题描述】:

我需要将一系列远程调用切成块。我想过使用演员。

我想到了这样的事情:

class ControlActor() extends Actor{
  var counter = 1000
  def act{
     for (i <- 1 until 1000) { new RequestActor(this) start }
    while(true){
      receive{
        case "Stop" =>{counter = counter-1; if(counter==0){return}}
      }
    } 
  }
}

class RequestActor(parent:ControlActor) extends actor{ ... }

但这有一个明显的问题:当我进入接收块时,一些 RequestActor 实例可能已经完成执行。如果他们向尚未处于消息接收状态的参与者发送消息会发生什么?消息是排队还是被丢弃?

最重要的是:我如何创建能够通知创建它们的 Actor 的子 Actor,即使它们返回得非常快?

还相关:将当前的 Actor 实例 (this) 传递给其他 Actor 是一种好习惯吗?由于某种原因,我没有看到有人这样做。

【问题讨论】:

  • 当我告诉每个使用 Scala actor 的问题时,请查看 Akka。它的真棒浓度非常高。

标签: scala actor


【解决方案1】:

你很好;演员中未处理的消息将简单地进入邮箱并在演员准备好时进行处理。然而,关于演员回复他们的调用者,您通常不需要传递对this 的引用,因为演员可以通过reply 直接与他们的调用者通信。这是一个简单的例子:

class MyActor(n: Int) extends Actor {
  def act() {
    loop {
      react {
        case m: Int => reply(n + m)  // Use `reply` to reply to caller
      }
    }
  }
}

// new MyActor(0), new MyActor(10), new MyActor(20), ...
val actors = (0 to 100 by 10) map (new MyActor(_).start())

// Message each actor with '5', expecting a response (that's what `!?` does)
val responses = actors map (_ !? 5)
responses foreach println

结果

5
15
25
35
45
55
65
75
85
95
105

然而,!? 操作符会阻塞主线程,直到我们得到对其消息的回复。因此,actors map (_ !? 5) 实际上并不是所有的并发。相反,您可以使用 !! 生成期货(您可以同时让计算并推迟评估,直到您准备好)。所以...将最后两行更改为

val futures = actors map (_ !! 5)
futures foreach (future => println(future()))

会给第一个演员发消息“5”,同时给我一个可以坚持的未来,然后给第二个演员发消息“5”,给我一个同时坚持的未来,等等,并且,当我们准备好时,我们可以评估未来 (future()) 并以某种方式使用其结果(例如打印出来)。

【讨论】:

    【解决方案2】:

    只要一个actor已经启动,发送给它的消息就会排队等待下一次receive/react调用。

    通过构造函数传递actor也可以,但是你应该将它们作为Actor而不是派生类型传递,以消除直接访问actor状态的诱惑。

    您通常不会看到这一点,因为通常演员是在消息中传递的。但你所做的并没有错。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-16
      • 2021-11-29
      • 1970-01-01
      • 2021-12-19
      • 1970-01-01
      • 2023-04-02
      相关资源
      最近更新 更多