在并行计算中正确使用期货

时间:2014-11-12 09:20:19

标签: scala

我实施的算法很容易并行化,但无法弄清楚如何创建适当数量的期货以及如何提前中止。目前,代码的轮廓沿着这些线

def solve: Boolean = {
  var result = false
  while(!result && i < iterations) {
    val futures = (1 to threads) map { _ => solveIter(geInitialValues()) }
    val loopResult = Future.fold(futures)(false)((acc, r) => acc || r )
    result = Await.result(loopResult, Duration.Inf)
    i+=1
  }
}

def solveIter(initialValues: Values): Future[Boolean] = Future {
  /* Takes a lot of time */
}

显而易见的问题是显式设置并行级别,可能适用于当前执行上下文,也可能不适合当前执行上下文。如果一次创建所有期货,如何让Future.fold提前中止?

1 个答案:

答案 0 :(得分:2)

您无法取消未来,因为期货是只读的。但你可以使用Promise,它是来自Future&#34;的写作部分。

示例代码:

  • 这段代码在5秒后超时,因为期货未完成(solveIter永远不会完成)
  • 完成承诺,删除评论,为“承诺”添加完整的承诺。 - 其他期货将被取消
  • 删除&#39; promises.foreach(_。trySuccess(false))&#39;并且你再次获得暂停,因为其他期货没有取消

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
import scala.concurrent.{Await, Future, Promise}
import scala.util.Try


// create a bunch of promises
val promises = ((1 to 10) map { _ =>
  val p = Promise[Boolean]()
  p.completeWith(solveIter())
  p
}) // :+ Promise().success(true)
// ^^ REMOVE THIS COMMENT TO ADD A PROMISE WHICH COMPLETES

// get the futures from the promises
val futures = promises.map(_.future)

// loop over all futures
futures.foreach(oneFuture =>
  // register callback when future is done
  oneFuture.foreach{
    case true =>
      println("future with 'true' result found")

      // stop others
      promises.foreach(_.trySuccess(false))

    case _ => // future completes with false
  })



// wait at most 5 seconds till all futures are done
Try(Await.ready(Future.sequence(futures), 5.seconds)).recover { case _ =>
  println("TIMEOUT")
}


def solveIter(): Future[Boolean] = Future {
  /* Takes a VERY VERY VERY .... lot of time */
  Try(Await.ready(Promise().future, Duration.Inf))
  false
}