processo figlio node.js - differenza tra spawn e fork


141

Potrebbe sembrare una domanda di base, ma non sono riuscito a trovare alcuna documentazione:

Qual è la differenza tra il fork e la generazione di un processo node.js? Ho letto che il biforcazione è un caso speciale di generazione, ma quali sono i diversi casi d'uso / ripercussioni per l'utilizzo di ciascuno di essi?

Risposte:


216

Spawn è un comando progettato per eseguire comandi di sistema. Quando si esegue spawn, si invia un comando di sistema che verrà eseguito sul proprio processo, ma non esegue alcun ulteriore codice all'interno del processo del nodo. Puoi aggiungere listener per il processo che hai generato, per consentire al tuo codice di interagire con il processo generato, ma non viene creata alcuna nuova istanza V8 (a meno che ovviamente il tuo comando non sia un altro comando Node, ma in questo caso dovresti usare fork!) E sul processore è attiva solo una copia del modulo nodo.

Fork è un'istanza speciale di spawn, che esegue una nuova istanza del motore V8. In altre parole, puoi essenzialmente creare più lavoratori, eseguendo esattamente la stessa base di codice Nodo o forse un modulo diverso per un'attività specifica. Questo è molto utile per creare un pool di lavoratori. Mentre il modello di eventi asincroni di nodo consente di utilizzare un singolo core di una macchina in modo abbastanza efficiente, non consente a un processo del nodo di utilizzare macchine multi-core. Il modo più semplice per ottenere ciò è eseguire più copie dello stesso programma, su un singolo processore.

Una buona regola empirica è uno o due processi nodo per core, forse più per macchine con un buon rapporto ram clock / cpu clock, o per processi nodo pesanti su I / O e leggeri su CPU, per ridurre al minimo i tempi di inattività dell'evento loop è in attesa di nuovi eventi. Tuttavia, quest'ultimo suggerimento è una micro-ottimizzazione e richiederebbe un'attenta valutazione comparativa per garantire che la vostra situazione si adatti alla necessità di molti processi / core. Puoi effettivamente ridurre le prestazioni generando troppi lavoratori per la tua macchina / scenario.

Alla fine potresti usare spawn in un modo che ha fatto quanto sopra, inviando spawn un comando Node. Ma sarebbe sciocco, perché fork fa alcune cose per ottimizzare il processo di creazione delle istanze V8. Solo chiarendo che alla fine si genera la forcella. Fork è semplicemente ottimale per questo caso d'uso particolare e molto utile.

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


@ChrisCM, se uso, var child = require('child_process').fork('child.js');ad esempio, sulla mia app principale, ora avrò 2 core separati in esecuzione. Se dovessi eseguire un ciclo pesante per il child.js (processo), essenzialmente utilizzerei più core per alimentare child.js, giusto? L'utilizzo della cpu influirebbe tuttavia sul mio core dell'app principale?
NiCk Newman,

2
È impossibile fare qualsiasi cosa su una CPU senza influire su altre cose. Pianificazione, utilizzo della cache condivisa, traffico BUS, ecc. Tuttavia, dovrebbe sfruttare un core separato e lasciare il ciclo di esecuzione principale PER MAGGIORMENTE inalterato. Come in, non i gravi effetti negativi che ti aspetteresti di avere due processi in esecuzione sullo stesso processore single core. A questo punto, dipende davvero dal sistema operativo e dalla configurazione dell'hardware ottimizzare in modo corretto. Configurazioni diverse possono produrre risultati diversi.
ChrisCM,

@ChrisCM Sì, uso un MonsterLoop globale per sincronizzare il posizionamento dei mostri e quell'oggetto che itera può arrivare a 5.000 chiavi. Ci ripeto ogni 2 secondi e il fork sembra che stia distruggendo centinaia di utilizzo della memoria dalla mia CPU (gioco principale). Preferirei farlo in questo modo invece di raggruppare quel loop out e farlo funzionare xx quantità di volte per core che avevo ... Ty per la tua intuizione ~ Ora non so se dovrei usare Redis o l'IPC interno: P
NiCk Newman,

2
Grazie per aver affrontato il "perché": tutti i post che ho letto fino a questo non hanno perso quella semplice parte della spiegazione.
aaaaaa,

@ChrisCM Nella tua risposta "..ma non esegue alcun ulteriore codice all'interno del processo del tuo nodo ...". Vuol dire che il thread principale è in attesa e non elabora nulla ... Se SÌ, a che serve usare spawn qui?
Abhi

9

TLDR

Spawn

Quando viene creata una spawn - Crea un'interfaccia di streaming tra processo genitore e figlio.

interfaccia di streaming significa - buffering dei dati in formato binario inONE TIME

Fork

Quando viene creato un fork - Crea un canale di comunicazione tra processo padre e figlio

canale di comunicazione significa - messaggistica

Difference

Beh, entrambi sembrano fare lo stesso trasferimento di dati , tranne la differenza sotto

spawn sarà utile quando si desidera eseguire un buffer di dati continuo in formato binario / di codifica , ad esempio: trasferire file video da 1 GB, immagini, file di registro inONE TIME

fork sarà utile quando si desidera eseguire messaggi, ad esempio messaggiJSON o XMLdati

Conslusion

uova deve essere utilizzato per lo streaming di dati di grandi dimensioni / files / immagini dal micelio processo per genitore processo

fork dovrebbe essere usato per fare messaggi Json / Xml.

  • Ad esempio, supponiamo che il processo 10 fork venga creato dal genitore.
  • e ogni processo esegue alcune operazioni
  • e ogni processo al completamento dell'operazione invierà un messaggio al genitore " processo n. 4 fatto ", " processo n. 8 fatto "

Che dire dei dati di registrazione continua dal genitore in un figlio e infine all'interno di un file?
Esqarrouth,

1
@Esqarrouth, è necessario identificare se si tratterà di flusso continuo o messaggi. E hai usato la parola "registrazione continua", credo che scriverai nei log (JSON) per figlio, Se sì, allora usa FORKaltro se hai una grande quantità di dati da BUFFERARE, quindi usaSPAWN
vijay

5
  • spawn - child_process.spawn avvia un nuovo processo con un determinato comando.
  • fork - Il metodo child_process.fork è un caso speciale di spawn () per creare processi figlio.

Il metodo spawn ()

Il metodo child_process.spawn avvia un nuovo processo con un determinato comando. Ha la seguente firma:

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

Ulteriori informazioni sulle opzioni

Il metodo spawn () restituisce flussi (stdout e stderr) e dovrebbe essere usato quando il processo restituisce un volume di dati. spawn () inizia a ricevere la risposta non appena il processo inizia l'esecuzione.

Il metodo fork ()

Il metodo child_process.fork è un caso speciale di spawn () per creare processi Node. Ha la seguente firma:

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

Il metodo fork restituisce un oggetto con un canale di comunicazione integrato oltre a disporre di tutti i metodi in un'istanza ChildProcess normale.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.