2009-12-31 26 views
8

Estoy aprendiendo, y realmente me gusta, el patrón Actor. Estoy usando Scala en este momento, pero estoy interesado en el estilo arquitectónico en general, ya que se usa en Scala, Erlang, Groovy, etc.¿Tiene sentido usar un grupo de Actores?

El caso en el que estoy pensando es en donde necesito hacer las cosas concurrentemente, como, digamos "ejecutar un trabajo".

Con roscado, me gustaría crear un grupo de subprocesos y una cola de bloqueo, y que cada sondeo de la cola de hilo de bloqueo, y procesar los trabajos a medida que entraba y salía de la cola.

Con actores, ¿cuál es la mejor manera de manejar esto? ¿Tiene sentido crear un grupo de actores, y de alguna manera enviarles mensajes conteniendo o los trabajos? ¿Quizás con un actor "coordinador"?

Nota: Un aspecto del caso, que se me olvidó mencionar fue: ¿y si quiero limitar el número de puestos de trabajo mi aplicación procesará simultáneamente? Tal vez con una configuración de configuración? Estaba pensando que un grupo podría hacer que sea más fácil hacer esto.

Gracias!

+1

Sí, tiene sentido limitar el número de actores que trabajan en una lista de tareas. Al menos, Erlang le da suficiente concurrencia para que pueda agotar la mayoría de los recursos del sistema al generar suficientes procesos para usarlos. – Christian

+0

He intentado reformular esta pregunta de una manera concreta, concreta y específica aquí: http://stackoverflow.com/questions/2312195/how-to-limit-concurrency-when-using-actors-in-scala –

Respuesta

4

A veces, tiene sentido limitar el número de procesos de trabajo que haya que operan simultáneamente en una lista de tareas grande, ya que la tarea del proceso se genera para completar implicar la asignación de recursos. Por lo menos, los procesos agotan la memoria, pero también pueden mantener abiertos los archivos y/o conectores que tienden a limitarse a solo miles y fallan miserablemente e impredecibles una vez que se agotan.

tener una piscina tarea tirón impulsada, uno puede generar N procesos vinculados que piden una tarea, y una parte de ellos una función que pueden spawn_monitor. Tan pronto como el proceso supervisado haya terminado, vuelven para la siguiente tarea. Las necesidades específicas manejan los detalles, pero ese es el esquema de un enfoque.

La razón por la que dejaría que cada tarea generar un nuevo proceso es que los procesos tienen algún estado y es agradable para empezar una pizarra limpia. Es un ajuste común establecer el tamaño mínimo de almacenamiento dinámico de los procesos para minimizar el número de GC necesarios durante su vida útil. También es una recolección de basura muy eficiente para liberar toda la memoria de un proceso y comenzar una nueva para la próxima tarea.

¿Se siente raro usar el doble de procesos así? Es una sensación que debes superar en la programación de Erlang.

+0

Muy interesante, gracias! Podría marcar esto como la respuesta "aceptada", tengo que pensar en esto. –

5

una piscina es un mecanismo que se utiliza cuando el costo de crear y derribar un recurso es alta. En Erlang, este no es el caso, por lo que no debe mantener un grupo.

Debe generar procesos a medida que los necesita y destruirlos cuando haya terminado con ellos.

+0

Gracias, pero ¿qué ocurre si quiero restringir el número de trabajos que mi aplicación procesará al mismo tiempo? Tal vez con una configuración de configuración? Estaba pensando que un grupo hace que sea fácil hacer esto. –

+3

@Avi: Creo que debe hacer una distinción aquí. Un "grupo" generalmente se refiere (al menos para mí) a preservar los actores/procesos y reutilizarlos. En Erlang no necesitas hacer eso, puedes tirarlos y generar otros nuevos. Por supuesto, puede implementar un "contador global" (en forma de un proceso de servidor, en una tabla de ets, etc.), que puede sondear antes de generar otro proceso de trabajo. De hecho, sí necesita alguna instalación como esta para lograr el control de la carga ... – Zed

+0

@Zed: buenos puntos, gracias. Tal vez debería haber preguntado "¿Cuál es una buena manera de limitar la concurrencia con los actores?" –

2

No existe la mejor manera para todos los casos. La decisión depende del número, la duración, la llegada y el tiempo requerido de finalización de los trabajos.

La diferencia más obvia entre simplemente destetar actores y usar pools es que en el primer caso sus trabajos se terminarán casi al mismo tiempo, mientras que en el último caso los tiempos de finalización se extenderán en el tiempo. Sin embargo, el tiempo promedio de finalización será el mismo.

La ventaja de utilizar actores es la simplicidad en la codificación, ya que no requiere manipulación adicional. La desventaja es que tus actores compiten por los núcleos de tu CPU.No podrá tener más trabajos paralelos que los núcleos de CPU (o HT's, lo que sea), independientemente del paradigma de programación que utilice.

Como ejemplo, imagine que necesita ejecutar 100'000 trabajos, cada uno con un minuto, y los resultados vencen el próximo mes. Tienes cuatro núcleos. ¿Engendrarías 100.000 actores que competirían por los recursos durante un mes o harías cola en tus trabajos y ejecutarías cuatro a la vez?

Como contraejemplo, imagina un servidor web ejecutándose en la misma máquina. Si tiene cinco solicitudes, ¿preferiría atender a cuatro usuarios en tiempo T, y uno en 2T, o servir los cinco en tiempo de 1.2T?

Cuestiones relacionadas