Node.js
Wielowątkowość
Szukaj…
Wprowadzenie
Node.js został zaprojektowany jako jednowątkowy. Tak więc dla wszystkich praktycznych celów aplikacje uruchamiane za pomocą Node będą działały w jednym wątku.
Jednak sam Node.js działa wielowątkowo. Operacje we / wy i tym podobne będą uruchamiane z puli wątków. Ponadto dowolne wystąpienie aplikacji węzła będzie działać na innym wątku, dlatego w celu uruchomienia aplikacji wielowątkowych uruchamia się wiele wystąpień.
Uwagi
Zrozumienie pętli zdarzeń jest ważne, aby zrozumieć, jak i dlaczego używać wielu wątków.
Grupa
Moduł cluster
umożliwia wielokrotne uruchomienie tej samej aplikacji.
Klastrowanie jest pożądane, gdy różne instancje mają ten sam przepływ wykonania i nie zależą od siebie. W tym scenariuszu masz jednego wzorca, który może uruchamiać widelce i widelce (lub dzieci). Dzieci pracują niezależnie i mają swoją jedyną przestrzeń Ram i Event Loop.
Konfigurowanie klastrów może być korzystne dla witryn / interfejsów API. Każdy wątek może służyć każdemu klientowi, ponieważ nie zależy od innych wątków. Baza danych (jak Redis) byłaby używana do udostępniania plików cookie, ponieważ zmiennych nie można udostępniać! między wątkami.
// 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');
Proces potomny
Procesy potomne są właściwą drogą, gdy chce się uruchamiać procesy niezależnie z różnymi inicjalizacjami i problemami. Podobnie jak rozwidlenia w klastrach, proces child_process
działa w swoim wątku, ale w przeciwieństwie do rozwidleń ma sposób komunikowania się z rodzicem.
Komunikacja przebiega w obie strony, więc rodzic i dziecko mogą nasłuchiwać wiadomości i wysyłać wiadomości.
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');
Dziecko (../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?');
})
Obok wiadomości można usłyszeć wiele zdarzeń, takich jak „błąd”, „połączony” lub „rozłącz”.
Rozpoczęcie procesu potomnego wiąże się z pewnym kosztem. Chcielibyśmy spawnować ich jak najmniej.