multithreading - sistemas - ¿Cómo, si es que lo hacen, los procesos de Erlang se asignan a los hilos del kernel?
procesos e hilos sistema operativo (4)
Erlang es conocido por ser capaz de soportar MUCHOS procesos ligeros; puede hacer esto porque estos no son procesos en el sentido tradicional, o incluso hilos como en los hilos P, sino hilos completamente en el espacio del usuario.
Esto es bueno y bueno (realmente fantástico). Pero, ¿cómo se ejecutan los subprocesos Erlang en paralelo en un entorno multinúcleo / multiprocesador? ¿Seguramente tienen que ser asignados de alguna manera a hilos del kernel para ser ejecutados en núcleos separados?
Suponiendo que ese es el caso, ¿cómo se hace esto? ¿Hay muchos procesos ligeros asignados a un solo hilo del kernel?
¿O hay otra manera de evitar este problema?
La respuesta depende de la máquina virtual que se utiliza:
1) no SMP : hay un programador (subproceso del sistema operativo), que ejecuta todos los procesos de Erlang, tomados del conjunto de procesos ejecutables (es decir, aquellos que no están bloqueados mediante la receive
por ejemplo)
2) SMP : hay K programadores (subprocesos del sistema operativo, K suele ser un número de núcleos de CPU), que ejecuta los procesos de Erlang desde la cola del proceso compartido . Es una cola FIFO simple (con bloqueos para permitir el acceso simultáneo desde múltiples subprocesos del sistema operativo).
3) SMP en R13B y más reciente : habrá K programadores (como antes) que ejecutan los procesos de Erlang desde múltiples colas de proceso . Cada programador tiene su propia cola, por lo que se agregará la lógica de migración del proceso de un programador a otro. Esta solución mejorará el rendimiento al evitar el bloqueo excesivo en la cola de procesos compartidos.
Para obtener más información, consulte este documento preparado por Kenneth Lundin, Ericsson AB, para la Conferencia de usuarios de Erlang, Estocolmo, 13 de noviembre de 2008.
Me gustaría agregar alguna información a lo que se describió en la respuesta aceptada.
Erlang Scheduler es la parte esencial del Sistema de Tiempo de Ejecución de Erlang y proporciona su propia abstracción e implementación de la concepción de procesos ligeros sobre los hilos del sistema operativo.
Cada programador se ejecuta dentro de un único hilo del sistema operativo. Normalmente, hay tantos programadores como CPU (núcleos) en el hardware (aunque es configurable y, naturalmente, no aporta mucho valor cuando el número de programadores excede a los de los núcleos de hardware). El sistema también podría estar configurado para que el programador no salte entre los subprocesos del sistema operativo.
Ahora, cuando se está creando el proceso de Erlang, es responsabilidad del ERTS y del programador gestionar el consumo de recursos y el ciclo de vida, así como su huella de memoria, etc.
Uno de los detalles básicos de la implementación es que cada proceso tiene un presupuesto de tiempo de 2000 reducciones disponibles cuando el Programador retira ese proceso de la cola de ejecución. Se garantiza que cada progreso en el sistema (incluso I / O) tiene un presupuesto de reducciones. Eso es lo que realmente hace de ERTS un sistema con multitarea preventiva.
Recomendaría una excelente publicación de blog sobre ese tema por Jesper Louis Andersen http://jlouisramblings.blogspot.com/2013/01/how-erlang-does-scheduling.html
Como respuesta corta: los procesos de Erlang no son hilos del sistema operativo y no se asignan directamente a ellos. Los programadores Erlang son lo que se ejecuta en los subprocesos del sistema operativo y proporcionan una implementación inteligente de procesos Erlang más detallados que ocultan esos detalles detrás de los ojos del programador.
Quiero enmendar las respuestas anteriores.
Erlang, o más bien el sistema de tiempo de ejecución Erlang (erts), establece por defecto el número de programadores (subprocesos del sistema operativo) y el número de colas de ejecución para el número de elementos de procesamiento en su plataforma. Eso es procesadores de núcleos o hilos de hardware. Puedes cambiar estas configuraciones en tiempo de ejecución usando:
erlang:system_flag(schedulers_online, NP) -> PrevNP
Los procesos de Erlang aún no tienen ninguna afinidad con ningún programador. La lógica que equilibra los procesos entre los planificadores sigue dos reglas. 1) Un programador hambriento robará el trabajo de otro programador. 2) Las rutas de migración se configuran para impulsar los procesos de los planificadores con muchos procesos a los planificadores con menos trabajo. Esto se hace para asegurar la equidad en el recuento de reducción (tiempo de ejecución) para cada proceso.
Sin embargo, los programadores se pueden bloquear a elementos de procesamiento específicos. Esto no se hace por defecto. Para que erts haga el uso de la afinidad del planificador -> núcleo:
erlang:system_flag(scheduler_bind_type, default_bind) -> PrevBind
Varios otros tipos de enlaces se pueden encontrar en la documentación. ¡El uso de la afinidad puede mejorar mucho el rendimiento en situaciones de carga pesada! Especialmente en situaciones de alta contención de bloqueo. Además, el kernel de Linux no puede manejar hyperthreads por decir lo menos. Si tiene hipervínculos en su plataforma, debería utilizar esta función en erlang.
Simplemente estoy adivinando aquí, pero me imagino que hay un pequeño número de subprocesos que seleccionan procesos de un grupo de procesos común para su ejecución. Una vez que un proceso llega a una operación de bloqueo, el hilo que lo ejecuta lo pone a un lado y elige otro. Cuando un proceso que se ejecuta hace que otro proceso se desbloquee, ese proceso recién desbloqueado se coloca en el grupo. Supongo que un hilo también puede detener la ejecución de un proceso, incluso cuando no está bloqueado en ciertos puntos para servir a otros procesos.