2012-01-24 18 views
17

Según tengo entendido, los actores son básicamente hilos livianos implementados en la parte superior de los hilos, ejecutando muchos actores en un pequeño grupo de hilos compartidos.scala actors vs hilos y bloqueo IO

Dado que es el caso, el uso de operaciones de bloqueo en un actor bloquea el hilo subyacente. Este no es un problema de corrección porque la biblioteca del actor generará más hilos según sea necesario (¿es correcto?) Pero luego terminará con muchos hilos, negando el beneficio de usar actores en primer lugar.

Dado que, ¿cómo funcionan los actores cuando necesita hacer tales operaciones de E/S? ¿Hay operaciones que bloquean al actor, suspendiendo al actor y dejando que el hilo pase a otras operaciones (al igual que las operaciones de bloqueo suspenden el hilo mientras se deja que la CPU pase a otras operaciones), o todo está escrito en CPS, con cadenas actores? ¿O los actores simplemente no son aptos para este tipo de operaciones de larga duración?

Antecedentes: Tengo experiencia escribiendo cosas multiproceso de la manera clásica, y entiendo muy bien cómo funcionan los CPS/eventos, pero no tengo absolutamente ninguna experiencia trabajando con actores, y solo quiero entender, en un alto nivel, cómo encajan. , antes de sumergirme en el código.

+1

Debe implicar en algún punto la continuación delimitada, como en http://jim-mcbeath.blogspot.com/2010/09/scala-coroutines.html. ¿O tal vez usar un flujo de mensajes sin bloqueo? (http://blog.typesafe.com/non-blocking-message-flow-with-akka-actors) – VonC

+0

Consulte mi respuesta aquí http://stackoverflow.com/questions/1512066/is-there-any-non -blocking-io-open-source-implementation-for-scalas-actors –

Respuesta

2

Esto no es un problema de corrección porque la biblioteca el actor se generan más hilos según sea necesario (¿es correcto eso?)

Por lo que yo entiendo, eso no es correcto. El actor está bloqueado y enviar otro mensaje hace que ese mensaje se guarde en el buzón de los actores hasta que el actor lo pueda receive o react al mensaje.

En Programación en Scala (1), establece explícitamente que los actores no deben bloquear. Si un actor necesita hacer algo de larga ejecución, debe pasar el trabajo a un segundo actor, de modo que el actor principal pueda liberarse e ir a leer más mensajes de su buzón. Una vez que el trabajador ha completado el trabajo, puede devolver ese hecho al actor principal, que puede terminar de hacer lo que tiene que hacer.

Dado que los trabajadores también tienen buzones de correo, terminarán con varios trabajadores trabajando afanosamente en su camino a través del trabajo. Si no tienes suficiente CPU para manejar eso, sus colas serán cada vez más grandes. Eventualmente puede escalar usando actores remotos. Akka podría ser más útil en tales casos.

(1) Capítulo 32.5 de Programación en Scala (Odersky, segunda edición, 2010)

EDIT: He encontrado esto:

El método planificador del rasgo Actor se puede anular para devolver una ResizableThreadPoolScheduler, que cambia el tamaño de su grupo de subprocesos para evitar la inanición causada por los actores que invocan métodos de bloqueo arbitrarios.

encontramos en: http://www.scala-lang.org/api/current/scala/actors/Actor.html

lo tanto, eso significa dependiendo del planificador impl configura, quizás la piscina se utiliza para ejecutar los actores se incrementará. Estaba equivocado cuando dije que estabas equivocado :-) El resto de la respuesta sigue siendo cierta.

1

Cómo funciona Erlang es que todas las operaciones de bloqueo se deben realizar enviando un mensaje porque cuando el actor está bloqueado esperando un mensaje, está cediendo el hilo a otro actor.

Así que si quieres hacer alguna operación de bloqueo, como leer un archivo, deberías hacer un editor de FileReader que use una API no bloqueante para leer y escribir desde un archivo. Y haga que su otro actor use este actor (envíe y reciba un mensaje) como una API para leer y escribir en un archivo.