2009-07-19 3 views
15

이론적으로 Scala Actor Framework를 사용하여 JDK 7의 Fork-Join 프레임 워크와 마찬가지로 일종의 비동기 Divide-and-conquer 계산을 수행 할 수 있습니까? 그렇다면 프레임 워크에서 FJ 문제를 어떻게 표현할 수 있습니까? 예를 들어 튜토리얼 병합 개념? 코드 스 니펫은 환영합니다. 스칼라 액터 프레임 워크를 fork-join 계산으로 사용 하시겠습니까?

는 (나는 내 ​​다른 FJ related question에 야해 resource video에 따라 생각을했다.)

답변

33

스칼라는 FJ 스타일의 병렬 처리를 가지고있다. 외침 선물이고 배우 도서관의 일부입니다.

import scala.actors.Future 
import scala.actors.Futures._ 

def mergeSort[A <% Ordered[A]](xs : List[A]) : List[A] = { 
    // merge is not interesting, it's sequential. The complexity lies in keeping it tail recursive 
    def merge[A <% Ordered[A]](accum : List[A], left : List[A], right : List[A]) : List[A] = { 
    (left, right) match { 
     case (lhead::ltail, rhead::rtail) => 
     if (lhead <= rhead) merge(lhead :: accum, ltail, right) 
     else merge(rhead :: accum, left, rtail) 
     case (Nil, _) => accum reverse_::: right 
     case _ => accum reverse_::: left 
    } 
    } 

    // here's the parallel sort bit 
    def sort[A <% Ordered[A]](xs : List[A], length : Int) : List[A] = { 
    if (length <= 1) xs 
    else { 
     val leftLength = length/2 
     val rightLength = length - leftLength 
     val (left, right) = xs splitAt leftLength 

     // fork 
     val leftFork = future { sort(left, leftLength) } 
     val rightFork = future { sort(right, rightLength) } 

     // join 
     val leftJoin = leftFork() 
     val rightJoin = rightFork() 

     // merge 
     merge(Nil, leftJoin, rightJoin) 
    } 
    } 

    sort(xs, xs.length) 
} 

지금, 질문의 핵심입니다. 스칼라에 선물이 없다면 액터를 기반으로 자신을 쓸 수 있습니까? 과연. 이것은 다소 비슷하게 보일 것입니다.

import scala.actors.Actor 
import scala.actors.Actor._ 

object MyFuture { 
    def apply[T](x : => T) : MyFuture[T] = { 
    val future = new MyFuture[T] 

    val act = actor { 
     react { 
     case sender : Actor => sender ! (future, x) 
     } 
    } 

    act ! self 

    future 

    } 
} 

class MyFuture[A] extends Function0[A] { 
    me => 

    lazy val result = receive { 
    case (`me`, result) => result.asInstanceOf[A] 
    } 

    def apply() = result 

}

그리고 당신이 그렇게

scala> val x = MyFuture(28 * 1000) 
x: Foo.MyFuture[Int] = <function> 

scala> x() 
res4: Int = 28000 
+0

와우처럼 사용하는 것입니다, 감사합니다. – akarnokd

+1

크기 400의 목록으로 FJ 예제를 시도했지만 CPU로드가 거의 들지 않습니다 (모든 코어에 100 %가되어야합니다). 그걸 설명하면 어떨까요? – awk

+0

이것을 어떻게 scala 2.10으로 재 작성하여 future() 차단을 사용하지 못하게 할 수 있습니까? – yura