2009-08-16 19 views
6

No entiendo la diferencia real (semántica) entre las dos "expresiones".
Se dice que "lazo" se ajusta a "reaccionar" y "mientras (verdadero)" a "recibir", porque "reaccionar" no regresa y "bucle" es una función que llama al cuerpo de nuevo (al menos esto es lo que deduzco de las fuentes: no estoy realmente familiarizado con el usado "y luego"). "Recibir" bloquea un hilo del grupo, "reaccionar" no. Sin embargo, para "reaccionar" se busca un hilo al que se pueda unir la función.¿Cuál es la diferencia entre while (true) y loop?

Entonces la pregunta es: ¿por qué no puedo usar "loop" con "receive"? También parece comportarse de manera diferente (¡y mejor!) Que la variante "while (true)", al menos esto es lo que observo en un generador de perfiles. Aún más extraño es llamar a un ping-pong con "-Dactors.maxPoolSize = 1 -Dactors.corePoolSize = 1" con "while (true)" y "recibir" bloques inmediatamente (eso es lo que esperaría) - sin embargo, con "loop" y "receive", funciona sin problemas, en un hilo, ¿cómo es esto?

Gracias!

+0

iirc la diferencia entre reaccionar y recibir es que recibir ocupa un hilo mientras que reacciona es un poco "inteligente" y ocupa uno cuando se necesita – Schildmeijer

+1

Gracias, agregué información a la pregunta, sin embargo, no explica la diferencia de tiempo (verdadero) y bucle y el patrón de uso que va: receive-> while (true), reaction-> loop. Para mí, receive-> loop también funcionaría y aún mejor ... – Ice09

Respuesta

2

El método loop se define en el objeto 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) 

Esto es confuso, pero lo que sucede es que el bloque que viene después de bucle (la cosa entre { y }) se pasa al método seq como primer argumento, y un nuevo ciclo con ese bloque se pasa como el segundo argumento.

En cuanto al método seq, en el rasgo Actor, encontramos:

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 
} 

Así, el nuevo bucle está prevista para la próxima acción después de una matanza, entonces el bloque es ejecutado, y luego una excepción de tipo KillActorException se lanza, lo que hará que el bucle se ejecute de nuevo.

Por lo tanto, un bucle while lleva a cabo mucho más rápido que un loop, ya que lanza sin excepciones, no hace la programación, etc. Por otra parte, el programador tiene la oportunidad de programar algo más entre dos ejecuciones de una loop.

+0

¿Es el último motivo (última oración) que hace posible utilizar 2 "recepciones" diferentes en solo un hilo (debido a la programación) con bucle? – Ice09

+0

Sí, pero, entonces, reaccionar es más rápido que recibir si no desea guardar el hilo para usted. –

4

La diferencia crítica entre while y loop es que while restringe el iteraciones del bucleque se produzca en el mismo hilo. La construcción loop (como se describe en Daniel) permite al subsistema actor invocar las reacciones en cualquier hilo que elija.

Por lo tanto, utilizando una combinación de receive dentro de while (true) vincula un actor a un solo hilo. Usando loop y reactle permite ejecutar el soporte de muchos actores en un solo hilo.

+0

Ok, entonces si combino el bucle y la recepción (que es la combinación en cuestión), ¿también podría ejecutarse la recepción en diferentes hilos? A partir de su explicación, entiendo que la combinación de while (t) y reaccionar no tendría ningún sentido (debido a la reacción de no retorno), pero no entiendo muy bien lo que significa loop/reaccionar. – Ice09

+0

Creo que si nos fijamos en la fuente de recepción que bloqueará el hilo actual. –

+0

(que está en el método 'suspendActor' y se llama desde' recibir') –

Cuestiones relacionadas