processus enfant node.js - différence entre spawn et fork

141

Cela peut sembler une question basique, mais je n'ai trouvé aucune documentation:

Quelle est la différence entre forking et engendrer un processus node.js? J'ai lu que la fourche est un cas particulier de frai, mais quels sont les différents cas d'utilisation / répercussions de l'utilisation de chacun d'eux?

Hitesh
la source

Réponses:

216

Spawn est une commande conçue pour exécuter des commandes système. Lorsque vous exécutez spawn, vous lui envoyez une commande système qui sera exécutée sur son propre processus, mais qui n'exécute aucun code supplémentaire dans votre processus de nœud. Vous pouvez ajouter des écouteurs pour le processus que vous avez généré, pour permettre à votre code d'interagir avec le processus généré, mais aucune nouvelle instance V8 n'est créée (à moins bien sûr que votre commande soit une autre commande Node, mais dans ce cas, vous devez utiliser fork!) Et une seule copie de votre module de nœud est active sur le processeur.

Fork est une instance spéciale de spawn, qui exécute une nouvelle instance du moteur V8. Cela signifie que vous pouvez essentiellement créer plusieurs nœuds de calcul, s'exécutant exactement sur la même base de code de nœud, ou peut-être un module différent pour une tâche spécifique. Ceci est très utile pour créer un pool de nœuds de calcul. Alors que le modèle d'événement asynchrone d'un nœud permet d'utiliser assez efficacement un seul cœur d'une machine, il ne permet pas à un processus de nœud d'utiliser des machines multicœurs. Le moyen le plus simple d'y parvenir est d'exécuter plusieurs copies du même programme sur un seul processeur.

Une bonne règle de base est un à deux processus de nœud par cœur, peut-être plus pour les machines avec un bon rapport horloge RAM / horloge processeur, ou pour les processus de nœud lourds en E / S et légers en travail CPU, afin de minimiser le temps d'arrêt de l'événement. loop attend de nouveaux événements. Cependant, cette dernière suggestion est une micro-optimisation et nécessiterait une analyse comparative minutieuse pour s'assurer que votre situation correspond au besoin de nombreux processus / cœur. Vous pouvez en fait réduire les performances en générant trop de nœuds de calcul pour votre machine / scénario.

En fin de compte, vous pouvez utiliser spawn d'une manière qui a fait ce qui précède, en envoyant spawn une commande Node. Mais ce serait idiot, car fork fait certaines choses pour optimiser le processus de création d'instances V8. Pour être clair, ce spawn englobe la fourche. Fork est tout simplement optimal pour ce cas d'utilisation particulier et très utile.

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

ChrisCM
la source
@ChrisCM, si j'utilise disons var child = require('child_process').fork('child.js');par exemple sur mon application principale, j'aurai maintenant 2 cœurs séparés en cours d'exécution. Si je devais exécuter une boucle for lourde dans le child.js (processus), j'utiliserais essentiellement plus de cœurs pour alimenter child.js, non? Cette utilisation du processeur affecterait-elle le cœur de mon application principale?
NiCk Newman
2
Il est impossible de faire quoi que ce soit sur un processeur sans effectuer d'autres choses. Planification, utilisation du cache partagé, trafic BUS, etc. Cependant, il devrait tirer parti d'un noyau séparé et laisser votre boucle d'exécution principale PRINCIPALEMENT inchangée. Comme dans, pas les effets négatifs graves que vous attendez de l'exécution de deux processus sur le même processeur monocœur. À ce stade, il appartient vraiment au système d'exploitation et à la configuration matérielle de s'optimiser correctement. Différentes configurations peuvent donner des résultats différents.
ChrisCM
@ChrisCM Oui, j'utilise un MonsterLoop global pour synchroniser le positionnement des monstres et cet objet qu'il itère peut contenir jusqu'à 5000 clés. Je l'itère toutes les 2 secondes et en forçant, il semble que cela détruit des centaines d'utilisation de la mémoire de mon processeur (jeu principal). Je préfère le faire de cette façon au lieu de regrouper cette boucle et de la faire fonctionner xx fois par cœur que j'avais ... Ty pour votre perspicacité ~ Maintenant, je ne sais tout simplement pas si je devrais utiliser Redis ou l'IPC interne: P
NiCk Newman
2
Merci d'avoir répondu «pourquoi» - tous les messages que j'ai lus jusqu'à celui-ci ont manqué cette simple partie de l'explication.
aaaaaa
@ChrisCM In vous répondez "..mais n'exécute aucun autre code dans votre processus de nœud ..". Cela signifie-t-il que le thread principal attend et ne traite rien ... Si OUI, à quoi sert d'utiliser spawn ici?
Abhi
9

TLDR

Spawn

Lorsqu'un spawn est créé - Il crée une interface de streaming entre les processus parent et enfant.

interface de streaming signifie - mise en mémoire tampon des données au format binaire dansONE TIME

Fork

Quand un fork est créé - Il crée un canal de communication entre le processus parent et enfant

moyen de canal de communication - messagerie

Difference

Eh bien, les deux semblent faire le même transfert de données , sauf différence ci-dessous

spawn sera utile lorsque vous souhaitez créer un tampon de données continu au format binaire / d'encodage , par exemple - Transférer un fichier vidéo de 1 Go, une image, des fichiers journaux dansONE TIME

fork sera utile lorsque vous voulez faire de la messagerie Par exemple -JSON ou de XMLla messagerie de données

Conslusion

spawn doit être utilisé pour le streaming de big data / fichiers / images FROM processus de spawn AU processus parent

fork doit être utilisé pour la messagerie Json / Xml.

  • Par exemple, supposons que 10 processus fork sont créés à partir du parent.
  • et chaque processus effectue une opération
  • et chaque processus à la fin de l'opération enverra un message au parent « processus n ° 4 terminé », « processus n ° 8 terminé »
vijay
la source
Qu'en est-il de l'enregistrement continu des données du parent dans un enfant et enfin dans un fichier?
Esqarrouth le
1
@Esqarrouth, vous devez identifier s'il s'agira d'un flux continu ou de messages. Et vous avez utilisé le mot "journalisation continue", je crois que vous allez écrire dans les journaux (JSON) à l'enfant, si oui, utilisez FORKautre si vous avez un très gros morceau de données à tamponner, puis utilisezSPAWN
vijay
5
  • spawn - child_process.spawn lance un nouveau processus avec une commande donnée.
  • fork - La méthode child_process.fork est un cas particulier de spawn () pour créer des processus enfants.

La méthode spawn ()

La méthode child_process.spawn lance un nouveau processus avec une commande donnée. Il a la signature suivante -

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

En savoir plus sur options

La méthode spawn () renvoie des flux (stdout & stderr) et elle doit être utilisée lorsque le processus renvoie une quantité volumique de données. spawn () commence à recevoir la réponse dès que le processus commence à s'exécuter.

La méthode fork ()

La méthode child_process.fork est un cas particulier de spawn () pour créer des processus Node. Il a la signature suivante -

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

La méthode fork renvoie un objet avec un canal de communication intégré en plus d'avoir toutes les méthodes dans une instance ChildProcess normale.

Igor Litvinovitch
la source