【问题标题】:Simple Scala actor question简单的 Scala 演员问题
【发布时间】:2010-04-02 03:16:18
【问题描述】:

我确定这是一个非常简单的问题,但不好意思说我无法理解它:

我在 Scala 中有一个值列表。 我想使用使用演员对每个值进行一些(外部)调用,并行。

我想等到所有值都处理完毕后再继续。

没有修改共享值。

谁能给点建议?

谢谢

【问题讨论】:

    标签: scala actor


    【解决方案1】:

    Scala 中有一个actor-using 类就是专门针对这类问题而设计的:Futures。这个问题可以这样解决:

    // This assigns futures that will execute in parallel
    // In the example, the computation is performed by the "process" function
    val tasks = list map (value => scala.actors.Futures.future { process(value) })
    
    // The result of a future may be extracted with the apply() method, which
    // will block if the result is not ready.
    // Since we do want to block until all results are ready, we can call apply()
    // directly instead of using a method such as Futures.awaitAll()
    val results = tasks map (future => future.apply())
    

    给你。就是这样。

    【讨论】:

    • 这太简单了,肯定有问题;-) 看起来不错,再次感谢。
    • @7zark7 是的,我也有这种感觉。 :-) 不过,它可以编译,而且我认为我没有犯任何特别的错误。确保process 不会引发异常,并注意如果您要执行 I/O,它可能不会像您预期的那样工作,因为正在运行的期货只会阻塞等待的线程。
    • 它有效。事实上,我对其进行了测试,以确保它能够像演员风格一样高效地执行多任务(我很好奇,因为我之前没有这样做过,也没有查看过Futures 源代码),确实如此。
    【解决方案2】:

    创建工人并使用!!向他们询问期货;然后读出结果(这些结果将被计算并在它们准备好时并行出现;然后您可以使用它们)。例如:

    object Example {
      import scala.actors._
      class Worker extends Actor {
        def act() { Actor.loop { react {
          case s: String => reply(s.length)
          case _ => exit()
        }}}
      }
      def main(args: Array[String]) {
        val arguments = args.toList
        val workers = arguments.map(_ => (new Worker).start)
        val futures = for ((w,a) <- workers zip arguments) yield w !! a
        val results = futures.map(f => f() match {
          case i: Int => i
          case _ => throw new Exception("Whoops--didn't expect to get that!")
        })
        println(results)
        workers.foreach(_ ! None)
      }
    }
    

    这是一个非常便宜的计算——计算一个字符串的长度——但是你可以放一些昂贵的东西来确保它确实并行发生(act 块的最后一件事应该是回复答案)。请注意,我们还包括一个工人关闭自己的案例,当我们都完成后,我们告诉工人关闭。 (在这种情况下,任何非字符串都会关闭工作人员。)

    我们可以尝试一下以确保它有效:

    scala> Example.main(Array("This","is","a","test"))
    List(4, 2, 1, 4)
    

    【讨论】:

    • 非常感谢 - 我似乎完全没有提到期货和使用!!在此之前。
    • 我应该指出,我可能对使用演员过于直白:如果你不打算重用它们,丹尼尔的回答会更短、更直接地获得你要求的并行计算. (即使用没有演员的期货。)
    • @Mog - f() 获取计算结果(阻塞直到可用)。 match 是因为演员发送的消息被键入为Any--我们期望得到一个 int 回来(所以我们寻找它),但如果我们出于某种意外原因得到其他东西,我们会抛出一个异常.
    猜你喜欢
    • 2012-07-28
    • 2011-08-31
    • 2010-10-03
    • 1970-01-01
    • 1970-01-01
    • 2011-01-20
    • 2011-01-30
    • 2019-04-23
    • 2011-02-20
    相关资源
    最近更新 更多