Simple Scala actor question

后端 未结 2 680
粉色の甜心
粉色の甜心 2021-02-06 04:53

I\'m sure this is a very simple question, but embarrassed to say I can\'t get my head around it:

I have a list of values in Scala. I would like to use use actors to make

相关标签:
2条回答
  • 2021-02-06 05:19

    Create workers and ask them for futures using !!; then read off the results (which will be calculated and come in in parallel as they're ready; you can then use them). For example:

    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)
      }
    }
    

    This does a very inexpensive computation--calculating the length of a string--but you can put something expensive there to make sure it really does happen in parallel (the last thing that case of the act block should be to reply with the answer). Note that we also include a case for the worker to shut itself down, and when we're all done, we tell the workers to shut down. (In this case, any non-string shuts down the worker.)

    And we can try this out to make sure it works:

    scala> Example.main(Array("This","is","a","test"))
    List(4, 2, 1, 4)
    
    0 讨论(0)
  • 2021-02-06 05:24

    There's an actor-using class in Scala that's made precisely for this kind of problem: Futures. This problem would be solved like this:

    // 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())
    

    There you go. Just that.

    0 讨论(0)
提交回复
热议问题