Chwytanie Node JS jako alternatywy dla wielowątkowości


142

Jeśli dobrze rozumiem, Node JS nie blokuje ... więc zamiast czekać na odpowiedź z bazy danych lub innego procesu, przeszedł do czegoś innego i sprawdził później.

Jest również jednowątkowy.

Czy to wszystko oznacza, że ​​dany proces Node JS może w pełni i efektywnie wykorzystywać pojedynczy rdzeń procesora, ale nie będzie używał żadnego innego rdzenia na maszynie, ponieważ nigdy nie będzie używał więcej niż jednego na raz.

To oczywiście oznacza, że ​​inne procesory mogą być nadal używane przez inne procesy do takich rzeczy, jak baza danych SQL lub inne celowo oddzielone podprogramy o dużej mocy obliczeniowej, o ile są oddzielnymi procesami.

Również w przypadku, gdy proces Node JS ma nieskończoną pętlę lub długotrwałą funkcję, proces ten nie jest już w żaden sposób przydatny, dopóki niekończąca się pętla lub długo działająca funkcja nie zostanie zatrzymana (lub cały proces zostanie zabity).

Czy to wszystko w porządku? Czy mam rację w moim rozumieniu?


2
„Węzeł” nie jest jednowątkowy. Tylko silnik JS / V8 działa w jednym wątku. Część libuv NodeJS jest wielowątkowa. Zobacz Czy NodeJS naprawdę jest jednowątkowy?
— RaelB

Odpowiedzi:


87

Prawie dobrze, tak. Serwer node.js ma wewnętrzną pulę wątków, dzięki czemu może wykonywać operacje blokujące i powiadamiać główny wątek za pomocą wywołania zwrotnego lub zdarzenia, gdy wszystko się zakończy.

Wyobrażam sobie więc, że będzie wykorzystywał w ograniczonym zakresie inny rdzeń dla puli wątków, na przykład jeśli wykonasz odczyt nieblokującego systemu plików, jest to prawdopodobnie zaimplementowane przez nakazanie wątkowi z puli wątków wykonania odczytu i ustawienia wywołania zwrotnego, gdy to się robi, co oznacza, że ​​odczyt może się odbywać w innym wątku / rdzeniu, podczas gdy główny program node.js robi coś innego.

Ale z punktu widzenia node.js jest całkowicie jednowątkowy i nie używa bezpośrednio więcej niż jednego rdzenia.


2
Nadal jestem nowy w Node.js i doceniam dyskusję tutaj. Chciałem tylko zwrócić uwagę, że przyjmowanie założeń, że połączenia nieblokujące są wspierane przez wywołania blokujące w wątkach, prawdopodobnie nie jest mądre (nie to, że @jcoder sugerował architekturę kodu wokół tych założeń). W tym przypadku, nawet jeśli IO jest obsługiwane w oddzielnym wątku z wywołaniem blokującym, ten wątek i tak będzie w zasadzie czekał na IO, więc nie będzie korzystał z innych rdzeni / procesorów. Koduj zgodnie z mocą używanych narzędzi i nie przejmuj się zbytnio szczegółami niskiego poziomu (dopóki nie staną się problemem).
— wbyoung

więc możemy robić inne prozy, używając wywołań zwrotnych, takich jak kod javascript na frontend
— yussan

37

Tak, powiedziałbym, że rozumiesz całkowicie poprawnie. Ten artykuł ( zarchiwizowany ) dość dobrze wyjaśnia uzasadnienie tego projektu. To chyba najważniejszy akapit:

Apache jest wielowątkowy: tworzy wątek na żądanie (lub proces, zależy to od konfiguracji). Możesz zobaczyć, jak ten narzut pochłania pamięć, gdy liczba równoczesnych połączeń wzrasta i potrzeba więcej wątków, aby obsłużyć wielu jednoczesnych klientów. Nginx i Node.js nie są wielowątkowe, ponieważ wątki i procesy wiążą się z dużymi kosztami pamięci. Są jednowątkowe, ale oparte na zdarzeniach. Eliminuje to obciążenie generowane przez tysiące wątków / procesów dzięki obsłudze wielu połączeń w jednym wątku.


Artykuł jest fałszywy. Chociaż istnieje wielowątkowy plik MPM Apache, jest on niekompatybilny z praktycznie wszystkimi codziennymi konfiguracjami. Apache jest wieloprocesowy i do tej pory nie był wielowątkowy i prawdopodobnie pozostanie na zawsze. Uważam, że to katastrofa, manipulowanie prawidłowymi znaczeniami terminologii to tylko miła próba ukrycia problemu, zamiast jego rozwiązania.
— peterh - Przywróć Monikę

1
@peterh Nie masz sensu. Artykuł jest całkowicie poprawny, stwierdzając, że apache jest wieloprocesowy lub wielowątkowy w zależności od konfiguracji. Sprawa wieloprocesowa jest jeszcze gorsza, jeśli chodzi o obsługę wielu połączeń, co jest jedynym powodem, dla którego wspomniano o Apache. Dodatkowo, bardzo często używany moduł PHP jest sam w sobie wielowątkowy. I wreszcie, chociaż nie jestem ekspertem od apaczy, moje wrażenie z innych artykułów jest takie, że robotniczy MPM jest w rzeczywistości bardzo powszechnie używany.
— Michael Borgwardt

@MichaelBorgwardt Tak, apache może być wielowątkowy, a także wieloprocesowy, nie zaprzeczałem. Ale php jest niekompatybilny z konfiguracją wieloprocesową i gdybyś był ekspertem od Apache, na pewno byś to wiedział. Bardzo często używany moduł php nie jest wielowątkowy. Twoje informacje są fałszywe. Proponuję wypróbować konfigurację testową, a zobaczysz. To rzecz faktyczna, nie podlega dyskusji, spróbuj, a zobaczysz.
— peterh - Przywróć Monikę

27

Nawet jeśli jest to stary wątek, pomyślałem, że podzielę się pomysłem, jak wykorzystać więcej niż jeden rdzeń w aplikacji Node.JS. Jak wspomniał Nuray Altin - JXcore to potrafi.

Prosty przykład:

var method = function () {
    console.log("this is message from thread no", process.threadId);
};

jxcore.tasks.runOnThread(0, method);
jxcore.tasks.runOnThread(1, method);

// this is message from thread no 1
// this is message from thread no 0

Domyślnie są dwa wątki (możesz to zmienić za pomocą jxcore.tasks.setThreadCount())

Oczywiście z zadaniami można zrobić znacznie więcej. Dokumenty są tutaj .

Kilka artykułów na ten temat:



1

Node.js jest aplikacją jednowątkową, ale może obsługiwać współbieżność poprzez koncepcję zdarzeń i wywołań zwrotnych. Oto wideo autorstwa Philipa Robertsa, które wyjaśnia, jak działają pętle zdarzeń w javascript.

Kliknij tu, aby zobaczyć film

(Zamiast interfejsów WebAPI w Node.js są C ++ API)


2
To powinien być komentarz
— Czerniow
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.