2009-08-16 2 views
6

두 표현식 사이에 실제 (의미) 차이가 없습니다.
"반응"이 돌아 오지 않고 "반복"이 몸을 다시 처음부터 다시 호출하는 기능이기 때문에 "반응"과 "while (true)"를 "수신"에 맞추는다고합니다. 이것은 내가 근원에서 공제 한 것입니다 - 저는 사용 된 "andThen"을 정말로 잘 모릅니다). "받기"는 풀에서 스레드 하나를 차단합니다. "반응"하지 않습니다. 그러나, "반응"을 위해 함수가 첨부 될 수있는 스레드가 조회됩니다.while (true)과 loop의 차이점은 무엇입니까?

질문 : "수신"과 함께 "루프"를 사용할 수없는 이유는 무엇입니까? 또한 "while (true)"변종보다 다르게 (그리고 더 좋습니다!) 행동하는 것처럼 보입니다. 적어도 이것이 프로파일 러에서 관찰하는 것입니다. "-Dactors.maxPoolSize = 1 -Dactors.corePoolSize = 1"로 "while (true)"및 "receive"블록 (즉, 내가 기대하는 것)을 사용하여 탁구를 호출하는 것이 더 이상합니다. "루프"와 "수신", 문제없이 작동 - 하나의 스레드에서 -이게 어때?

감사합니다.

+0

iirc 반응과 수신 사이의 차이는 반응 수신 중에 스레드가 조금 더 똑똑하고 만족스럽지 않을 때 발생합니다. – Schildmeijer

+1

감사합니다. 질문에 대한 정보를 추가했습니다. (참) 및 루프와 이동 사용 패턴 : 수신 -> 동안 (사실), react-> 루프. 나를 위해, 수신 -> 루프도 작동하고 더 나은 것 ... – Ice09

답변

2

방법 loop은 객체 Actor에 정의되어

private[actors] trait Body[a] { 
    def andThen[b](other: => b): Unit 
} 

implicit def mkBody[a](body: => a) = new Body[a] { 
    def andThen[b](other: => b): Unit = self.seq(body, other) 
} 

/** 
* Causes <code>self</code> to repeatedly execute 
* <code>body</code>. 
* 
* @param body the code block to be executed 
*/ 
def loop(body: => Unit): Unit = body andThen loop(body) 

이 혼란이지만, 무슨 일 루프 ({} 사이의 것) 다음에 오는 블록이 방법 seq에 전달되는 것입니다 첫 번째 인수로, 그리고 그 블록을 가진 새로운 루프가 두 번째 인수로 전달됩니다. 방법 seq에 관해서는

, 형질 Actor, 우리는 찾을 수 :

private def seq[a, b](first: => a, next: => b): Unit = { 
    val s = Actor.self 
    val killNext = s.kill 
    s.kill =() => { 
    s.kill = killNext 

    // to avoid stack overflow: 
    // instead of directly executing `next`, 
    // schedule as continuation 
    scheduleActor({ case _ => next }, 1) 
    throw new SuspendActorException 
    } 
    first 
    throw new KillActorException 
} 

그래서, 새로운 루프가 살인 후 다음 동작에 예정되어 다음 블록은 예외가 다음 실행 및 도착 이 경우 KillActorException 유형이 throw되어 루프가 다시 실행됩니다.

그래서하는 while 루프는 예외를 throw하지 않기 때문에, 훨씬 빠르게 loop이 수행하는 한편 더 스케줄링 등, 스케줄러는 loop의 두 실행 사이 다른 뭔가를 예약 할 수있는 기회를 얻을하지 않습니다.

+0

루프를 사용하여 하나의 스레드에서만 2 개의 다른 "수신"을 사용할 수있는 마지막 이유 (마지막 문장)입니까? – Ice09

+0

예, 그렇지만, 스레드가 스스로를 유지하고 싶지 않은 경우 반응은 수신보다 빠릅니다. –

4

whileloop 사이의 중요한 차이는 while이 동일한 스레드 발생하는 루프 반복을 제한한다는 것이다. (다니엘 설명된다) loop 구조체는 선택한 모든 스레드에 반응을 호출 액터 서브 시스템을 가능하게한다.

receive에서 while (true)의 조합을 사용하면 하나의 스레드에 액터를 연결할 수 있습니다. loopreact을 사용하면 단일 스레드에 많은 배우를 지원 실행할 수 있습니다.

+0

루프를 결합하고 문제의 조합 인 receive를 수신하면 receive가 다른 스레드에서 실행될 수 있습니까? 귀하의 설명에서 나는 while (t)와 react의 조합이 (반응의 비 반환으로 인해) 전혀 이해가되지 않을 것이라고 이해하지만, 루프/반응의 함의를 얻지는 못합니다. – Ice09

+0

내가 현재 스레드를 차단한다는 것을 수신자가 보았다면 생각합니다. –

+0

(이는'suspendActor' 메쏘드에 있고'receive'에서 호출됩니다) –

관련 문제