The reply最近我的一个问题表明,一个演员一次处理一个的消息。这是真的?我没有看到任何明确说明(在 Scala编程中),其中包含以下代码段(第593页)
如果[
react
方法]找到可以处理的消息,[it]将安排处理该消息以便以后执行并抛出异常
(强调我自己)。两个相关(和相互排斥)的问题:
receive
?)编辑:做一些测试似乎证明我错了,演员确实是连续的。所以问题#2我需要回答
答案 0 :(得分:26)
Actors一次处理一条消息。处理多个消息的经典模式是为消费者角色池设置一个协调者角色。如果使用react,则使用者池可能很大,但仍然只使用少量JVM线程。这是一个例子,我为他们创建了一个由10个消费者和一个协调员组成的池。
import scala.actors.Actor
import scala.actors.Actor._
case class Request(sender : Actor, payload : String)
case class Ready(sender : Actor)
case class Result(result : String)
case object Stop
def consumer(n : Int) = actor {
loop {
react {
case Ready(sender) =>
sender ! Ready(self)
case Request(sender, payload) =>
println("request to consumer " + n + " with " + payload)
// some silly computation so the process takes awhile
val result = ((payload + payload + payload) map {case '0' => 'X'; case '1' => "-"; case c => c}).mkString
sender ! Result(result)
println("consumer " + n + " is done processing " + result )
case Stop => exit
}
}
}
// a pool of 10 consumers
val consumers = for (n <- 0 to 10) yield consumer(n)
val coordinator = actor {
loop {
react {
case msg @ Request(sender, payload) =>
consumers foreach {_ ! Ready(self)}
react {
// send the request to the first available consumer
case Ready(consumer) => consumer ! msg
}
case Stop =>
consumers foreach {_ ! Stop}
exit
}
}
}
// a little test loop - note that it's not doing anything with the results or telling the coordinator to stop
for (i <- 0 to 1000) coordinator ! Request(self, i.toString)
此代码测试以查看哪个消费者可用并向该消费者发送请求。替代方案是随机分配给消费者或使用循环调度程序。
根据您的工作情况,您可能会更好地使用Scala的期货。例如,如果你真的不需要演员,那么所有上述机器都可以写成
import scala.actors.Futures._
def transform(payload : String) = {
val result = ((payload + payload + payload) map {case '0' => 'X'; case '1' => "-"; case c => c}).mkString
println("transformed " + payload + " to " + result )
result
}
val results = for (i <- 0 to 1000) yield future(transform(i.toString))
答案 1 :(得分:6)
我认为答案是Actor
无法异步处理消息。如果你有一个Actor
应该收听消息,这些消息可以异步处理,那么可以这样写:
val actor_ = actor {
loop {
react {
case msg =>
//create a new actor to execute the work. The framework can then
//manage the resources effectively
actor {
//do work here
}
}
}
}
答案 2 :(得分:0)
如果你想做多件事,那么你应该使用多个演员。使用参与者的全部理由是在多个独立过程之间划分工作。
答案 3 :(得分:0)
您可以尝试使用期货概念。请使用期货存储所有这些消息,然后尝试处理所有这些消息。