Proceso hijo de node.js: diferencia entre spawn y fork


141

Esto puede parecer una pregunta básica, pero no pude encontrar ninguna documentación:

¿Cuál es la diferencia entre bifurcar y generar un proceso node.js? He leído que la bifurcación es un caso especial de desove, pero ¿cuáles son los diferentes casos de uso / repeticiones para usar cada uno de ellos?

Respuestas:


215

Spawn es un comando diseñado para ejecutar comandos del sistema. Cuando ejecuta spawn, le envía un comando del sistema que se ejecutará en su propio proceso, pero no ejecuta ningún código adicional dentro de su proceso de nodo. Puede agregar oyentes para el proceso que ha generado, para permitir que su código interactúe con el proceso generado, pero no se crea una nueva instancia de V8 (a menos, por supuesto, que su comando sea otro comando Node, ¡pero en este caso debe usar fork!) Y solo una copia de su módulo de nodo está activa en el procesador.

Fork es una instancia especial de spawn, que ejecuta una nueva instancia del motor V8. Es decir, esencialmente puede crear múltiples trabajadores, ejecutándose exactamente en la misma base de código de Nodo, o tal vez un módulo diferente para una tarea específica. Esto es más útil para crear un grupo de trabajadores. Si bien el modelo de evento asíncrono de nodo permite que un solo núcleo de una máquina se use de manera bastante eficiente, no permite que un proceso de nodo utilice máquinas de múltiples núcleos. La forma más fácil de lograr esto es ejecutar múltiples copias del mismo programa, en un solo procesador.

Una buena regla general es uno o dos procesos de nodo por núcleo, tal vez más para máquinas con una buena relación de reloj ram / CPU, o para procesos de nodo pesados ​​en E / S y poco trabajo de CPU, para minimizar el tiempo de inactividad del evento loop está esperando nuevos eventos. Sin embargo, la última sugerencia es una microoptimización y necesitaría una evaluación comparativa cuidadosa para garantizar que su situación se adapte a la necesidad de muchos procesos / núcleos. En realidad, puede disminuir el rendimiento generando demasiados trabajadores para su máquina / escenario.

En última instancia, podría usar spawn de una manera que hizo lo anterior, enviando a spawn un comando Node. Pero esto sería una tontería, porque fork hace algunas cosas para optimizar el proceso de creación de instancias de V8. Simplemente dejándolo claro, ese engendro en última instancia abarca tenedor. La horquilla es óptima para este caso de uso particular y muy útil.

http://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback


@ChrisCM, si uso, var child = require('child_process').fork('child.js');por ejemplo, en mi aplicación principal, ahora tendré 2 núcleos separados ejecutándose. Si tuviera que ejecutar un ciclo for pesado en el proceso child.js, esencialmente estaría utilizando más núcleos para alimentar child.js, ¿verdad? ¿Sin embargo, el uso de la CPU afectaría el núcleo principal de mi aplicación?
NiCk Newman

2
Es imposible hacer algo en una CPU sin afectar otras cosas. Programación, uso de caché compartida, tráfico de BUS, etc. Sin embargo, debe aprovechar un núcleo separado y dejar su ciclo de ejecución principal SIN MAYOR alteración. Como en, no los graves efectos negativos que esperarías de tener dos procesos ejecutados en el mismo procesador de un solo núcleo. En este punto, depende realmente del sistema operativo y la configuración del hardware para optimizar correctamente. Diferentes configuraciones pueden dar resultados diferentes.
ChrisCM

@ChrisCM Sí, uso un MonsterLoop global para sincronizar el posicionamiento del monstruo y ese objeto que itera puede ser de hasta 5,000 teclas. Repito cada 2 segundos y bifurcando parece que está eliminando cientos de uso de memoria de mi CPU (juego principal). Preferiría hacerlo de esta manera en lugar de agrupar ese bucle y hacer que se ejecute xx cantidad de veces por núcleo que tenía ... Ty para su comprensión ~ Ahora no sé si debería usar Redis o el IPC interno: P
NiCk Newman

2
Gracias por abordar "por qué": todas las publicaciones que leí hasta que se perdieron esa simple parte de la explicación.
aaaaaa

@ChrisCM En su respuesta "... pero no ejecuta ningún código adicional dentro de su proceso de nodo ...". ¿Significa que el hilo principal está esperando y no procesa nada? Si es SÍ, ¿de qué sirve usar spawn aquí?
Abhi

9

TLDR

Spawn

Cuando se crea un spawn : crea una interfaz de transmisión entre el proceso primario y secundario.

interfaz de transmisión significa : almacenamiento en búfer de datos en formato binario enONE TIME

Fork

Cuando se crea una bifurcación : crea un canal de comunicación entre el proceso primario y secundario

canal de comunicación significa - mensajería

Difference

Bueno, ambos parecen hacer la misma transferencia de datos , excepto la diferencia a continuación

spawn será útil cuando desee hacer un búfer de datos continuo en formato binario / codificación , por ejemplo, transferir archivos de video de 1 gb, imágenes, archivos de registro enONE TIME

fork será útil cuando desee enviar mensajes, por ejemplo, JSONo XMLmensajes de datos

Conslusion

desove se debe utilizar para la transmisión de grandes volúmenes de datos / archivos / imágenes desde desove proceso para padres proceso

fork se debe usar para hacer mensajes Json / Xml.

  • Por ejemplo, supongamos que se crean 10 tenedores a partir del padre.
  • y cada proceso realiza alguna operación
  • y cada proceso al completar la operación enviará un mensaje al padre ' proceso no 4 terminado ', ' proceso no 8 terminado '

¿Qué pasa con los datos de registro continuo de padre a hijo y finalmente dentro de un archivo?
Esqarrouth

1
@Esqarrouth, debe identificar si será una transmisión continua o mensajes. Y usó la palabra "registro continuo", creo que estará escribiendo a los registros (JSON) al niño, en caso afirmativo, use FORKotra cosa si tiene una gran cantidad de datos para BUFFERED luego useSPAWN
vijay

5
  • spawn - child_process.spawn inicia un nuevo proceso con un comando dado.
  • fork : el método child_process.fork es un caso especial de spawn () para crear procesos secundarios.

El método spawn ()

El método child_process.spawn inicia un nuevo proceso con un comando dado. Tiene la siguiente firma:

child_process.spawn(command[, args][, options])

Leer más sobre opciones

El método spawn () devuelve flujos (stdout y stderr) y debe usarse cuando el proceso devuelve una cantidad de datos en volumen. spawn () comienza a recibir la respuesta tan pronto como el proceso comienza a ejecutarse.

El método fork ()

El método child_process.fork es un caso especial de spawn () para crear procesos Node. Tiene la siguiente firma:

 child_process.fork(modulePath[, args][, options])

El método fork devuelve un objeto con un canal de comunicación incorporado además de tener todos los métodos en una instancia ChildProcess normal.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.