繁体   English   中英

对期货做出反应

[英]React for futures

我试图使用分而治之(又称fork / join)方法来解决数字运算问题。 这是代码:

import scala.actors.Futures.future

private def compute( input: Input ):Result = {
  if( pairs.size < SIZE_LIMIT ) {
    computeSequential()
  } else {
    val (input1,input2) = input.split
    val f1 = future( compute(input1) )
    val f2 = future( compute(input2) )
    val result1 = f1()
    val result2 = f2()
    merge(result1,result2)
  }
}

它运行(具有良好的加速)但未来的apply方法似乎阻塞了一个线程,并且线程池大大增加。 并且当创建太多线程时,计算被卡住。

是否存在一种释放线程的期货反应方法? 或任何其他方式来实现这种行为?

编辑:我使用scala 2.8.0.final

不要求(申请)你的Future ,因为这迫使他们阻止并等待答案; 正如你所见,这可能会导致死锁。 相反,单独使用它们告诉他们完成后该怎么做。 代替:

val result1 = f1()
val result2 = f2()
merge(result1,result2)

尝试这个:

for {
  result1 <- f1
  result2 <- f2
} yield merge(result1, result2)

结果将是包含合并结果的Responder[Result] (基本上是Future[Result] ); 你可以使用response respond()foreach() respond()这个最终值做一些有效的事情,或者你可以将map()flatMap() map()到另一个Responder[T] 不需要阻止,只需保持计划未来的计算!

编辑1:

好的, compute功能的签名现在必须更改为Responder[Result] ,那么这对递归调用有何影响? 我们试试这个:

private def compute( input: Input ):Responder[Result] = {
  if( pairs.size < SIZE_LIMIT ) {
    future(computeSequential())
  } else {
    val (input1,input2) = input.split
    for {
      result1 <- compute(input1)
      result2 <- compute(input2)
    } yield merge(result1, result2)
  }
}

现在你不再需要用future(...)包含对compute的调用,因为它们已经返回ResponderFuture的超类)。

编辑2:

使用这种延续传递方式的一个结果是,您的顶级代码 - 无论是最初的compute调用 - 都不再阻止。 如果它是从main()调用的,并且这是所有程序所做的,这将是一个问题,因为现在它只会产生一堆未来,然后立即关闭,完成它被告知要做的所有事情。 您需要做的是block所有这些未来,但只在顶级,只在所有计算的结果,而不是任何中间的结果。

不幸的是,这个被compute()返回的Responder事件不再像Future那样有一个阻塞的apply()方法。 我不确定为什么flatMapping Future会生成一个通用的Responder而不是Future 这似乎是一个API错误。 但无论如何,你应该能够自己创造:

def claim[A](r:Responder[A]):A = {
  import java.util.concurrent.ArrayBlockingQueue
  import scala.actors.Actor.actor

  val q = new ArrayBlockingQueue[A](1)
  // uses of 'respond' need to be wrapped in an actor or future block
  actor { r.respond(a => q.put(a)) } 
  return q.take
}

所以现在你可以在main方法中创建一个阻塞调用来计算,如下所示:

val finalResult = claim(compute(input))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM