Простой актер Scala

Я уверен, что это очень простой вопрос, но мне стыдно сказать, что я не могу разобраться с этим:

У меня есть список значений в Scala. Я хотел бы использовать актеры для параллельных вызовов (внешних) вызовов с каждым значением.

Я хотел бы подождать, пока все значения не будут обработаны, а затем продолжить.

Там нет общих значений, которые будут изменены.

Кто-нибудь может посоветовать?

Спасибо

8
задан 7zark7 2 April 2010 в 03:16
поделиться

2 ответа

В Scala есть класс, использующий акторов, который создан именно для такого рода задач: 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())

Вот и все. Только то.

17
ответ дан 5 December 2019 в 06:22
поделиться

Создавайте рабочих и спрашивайте их о фьючерсах, используя !! ; затем считайте результаты (которые будут рассчитаны и поступать параллельно по мере готовности; затем вы можете их использовать). Например:

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)
9
ответ дан 5 December 2019 в 06:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: