2016-06-28 1 views
1

두 개의 스칼라 함수를 실행하는 데 비용이 많이 듭니다. 각각은 아래와 같이 변수 값을 향상시키기 시작하고 동시에 5 분 (또는 다른 시간) 후에 변수를 실행하고 싶습니다. 나는 두 가지 기능을 종료하고 최신 값을 그 시간까지 가져 가고 싶습니다.병렬로 두 개의 스칼라 함수를 실행하고 5 분 후에 최신 값을 반환합니다.

def func1(n: Int): Double = { 
    var a = 0.0D 
    while (not terminated) { 
     /// improve value of 'a' with algorithm 1 
    } 
} 

def func2(n: Int): Double = { 
    var a = 0.0D 
    while (not terminated) { 
     /// improve value of 'a' with algorithm 2 
    } 
} 

여기 코드를 어떻게 구조화해야하는지 알고 싶습니다. 여기서 가장 좋은 방법은 무엇입니까? 시간 초과와 함께 두 개의 다른 스레드에서 실행하고 시간 초과시 최신 값을 반환하는 방법에 대해 생각했습니다. 그러나 그렇게하기위한 다른 방법이있을 수 있습니다. 나는 어떤 통찰력이라도 대단히 도움이 될 수 있도록 Scala를 처음 사용합니다.

답변

1

어렵지 않습니다.

@volatile var terminated = false 

    def func1(n: Int): Double = { 
    var a = 0.0D 
    while (!terminated) { 
     a = 0.0001 + a * 0.99999; //some useless formula1 
    } 
    a 
    } 

    def func2(n: Int): Double = { 
    var a = 0.0D 
    while (!terminated) { 
     a += 0.0001 //much simpler formula2, just for testing 
    } 
    a 
    } 


    def main(args: Array[String]): Unit = { 

    val f1 = Future { func1(1) } //work starts here 

    val f2 = Future { func2(2) } //and here 

    //aggregate results into one common future 
    val aggregatedFuture = for{ 
     f1Result <- f1 
     f2Result <- f2 
    } yield (f1Result, f2Result) 

    Thread.sleep(500) //wait here for some calculations in ms 
    terminated = true //this is where we actually command to stop 

    //since looping to while() takes time, we need to wait for results 
    val res = Await.result(aggregatedFuture, 50.millis) 
    //just a printout 
    println("results:" + res) 

} 

는하지만, 물론, 당신은 아마 당신의 동안 루프보고보다 관리 및 체인 방식 계산을 만들 것입니다 : 여기에 그 일을하는 한 가지 방법이다.

출력 : results:(9.999999999933387,31206.34691883926)

2

나는 이것이 당신이 원하는 것이 무엇인가,하지만 여기에 한 가지 방법 인 경우 100 % 확실하지 (5 분,하지만 당신은 변경할 수 없습니다) 오전 :

object s 
{ 
    def main(args: Array[String]): Unit = println(run()) 

    def run(): (Int, Int) = 
    { 
     val (s, numNanoSec, seedVal) = (System.nanoTime, 500000000L, 0) 
     Seq(f1 _, f2 _).par.map(f => 
     { 
      var (i, id) = f(seedVal) 
      while (System.nanoTime - s < numNanoSec) 
      { 
       i = f(i)._1 
      } 
      (i, id) 
     }).seq.maxBy(_._1) 
    } 
    def f1(a: Int): (Int, Int) = (a + 1, 1) 
    def f2(a: Int): (Int, Int) = (a + 2, 2) 
} 

출력 : 물론

[email protected]:~/junk> scala s.scala 
(34722678,2) 
[email protected]:~/junk> scala s.scala 
(30065688,2) 
[email protected]:~/junk> scala s.scala 
(34650716,2) 

이 모든 당신이 작업에 배포 할 수 적어도 두 개의 스레드를 가정합니다.

+1

이것은 이후 더 나은 방법입니다 반환 그것은 부작용에 의존하지 않고 평범한 코드가 어떻게 생겼는지에 더 가깝습니다. 나는 초보자에게 더 직관적이되도록 노력했다. –

0

당신이 할 Await 결과 Future를 사용할 수 있습니다

def fun2(): Double = { 
    var a = 0.0f 
    val f = Future { 
     // improve a with algorithm 2 
     a 
    } 
    try { 
     Await.result(f, 5 minutes) 
    } catch { 
     case e: TimeoutException => a 
    } 
    } 

가 타임 아웃 algorithm을 기다리도록 Await.result를 사용하여 우리는이 시간 제한을 만났을 때, 우리는 a 직접

관련 문제