Node.js
multithreading
Ricerca…
introduzione
Node.js è stato progettato per essere thread singolo. Quindi, per tutti gli scopi pratici, le applicazioni che si avviano con Node verranno eseguite su un singolo thread.
Tuttavia, Node.js stesso esegue multi-thread. Le operazioni di I / O e simili verranno eseguite da un pool di thread. Inoltre, qualsiasi istanza di un'applicazione nodo viene eseguita su un thread diverso, pertanto per eseguire applicazioni multi-thread si avviano più istanze.
Osservazioni
Grappolo
Il modulo cluster
consente di avviare la stessa applicazione più volte.
Il clustering è auspicabile quando le diverse istanze hanno lo stesso flusso di esecuzione e non dipendono l'una dall'altra. In questo scenario, hai un master che può avviare fork e fork (o figli). I bambini lavorano indipendentemente e hanno il loro unico spazio di Ram ed Event Loop.
La configurazione dei cluster può essere utile per i siti Web / le API. Qualsiasi thread può servire qualsiasi cliente, in quanto non dipende da altri thread. Un database (come Redis) verrebbe utilizzato per condividere cookie, in quanto le variabili non possono essere condivise! tra i fili.
// runs in each instance
var cluster = require('cluster');
var numCPUs = require('os').cpus().length;
console.log('I am always called');
if (cluster.isMaster) {
// runs only once (within the master);
console.log('I am the master, launching workers!');
for(var i = 0; i < numCPUs; i++) cluster.fork();
} else {
// runs in each fork
console.log('I am a fork!');
// here one could start, as an example, a web server
}
console.log('I am always called as well');
Processo figlio
I processi figlio sono la strada da seguire quando si desidera eseguire processi in modo indipendente con diverse inizializzazioni e preoccupazioni. Come i fork nei cluster, un child_process
viene eseguito nel thread, ma a differenza dei fork, ha un modo di comunicare con i suoi genitori.
La comunicazione va in entrambe le direzioni, quindi genitore e figlio possono ascoltare i messaggi e inviare messaggi.
Parent (../parent.js)
var child_process = require('child_process');
console.log('[Parent]', 'initalize');
var child1 = child_process.fork(__dirname + '/child');
child1.on('message', function(msg) {
console.log('[Parent]', 'Answer from child: ', msg);
});
// one can send as many messages as one want
child1.send('Hello'); // Hello to you too :)
child1.send('Hello'); // Hello to you too :)
// one can also have multiple children
var child2 = child_process.fork(__dirname + '/child');
Bambino (../child.js)
// here would one initialize this child
// this will be executed only once
console.log('[Child]', 'initalize');
// here one listens for new tasks from the parent
process.on('message', function(messageFromParent) {
//do some intense work here
console.log('[Child]', 'Child doing some intense work');
if(messageFromParent == 'Hello') process.send('Hello to you too :)');
else process.send('what?');
})
Accanto al messaggio si possono ascoltare molti eventi come "errore", "connesso" o "disconnessione".
L'avvio di un processo secondario comporta un certo costo associato. Si vorrebbe generare il maggior numero possibile di loro.