Event-Schleife mit einem einzelnen Thread und nicht blockierendem Multi-Threading-Worker in Node.JS

7

Node.JS größter Vorteil ist es nicht blockierende Natur. Es ist single-threaded, also muss nicht für jede neue eingehende Verbindung ein neuer Thread erstellt werden.

Hinter der Ereignisschleife (die tatsächlich single threaded ist) gibt es einen "Non blocking Worker". Dieses Ding ist nicht mehr single threaded, also (soweit ich das verstanden habe) kann es einen neuen Thread für jede Aufgabe erzeugen.

Vielleicht habe ich etwas falsch verstanden, aber wo genau ist der Vorteil. Wenn es zu viele zu behandelnde Aufgaben gibt, würde sich das nicht blockierende Arbeiten nicht in einen blockierenden Arbeiter verwandeln?

Danke Christ

    
Christian 31.01.2014, 17:08
quelle

3 Antworten

27

Sie müssen über libuv lesen, die "Magie" hinter den nicht blockierenden I / O-Knoten des Knotens.

Wichtig ist, dass Libuv das asynchrone I/O Einrichtungen ; Es wird nicht einfach ein neuer Thread für jede Verbindung erstellt.

libuv teilt dem Betriebssystem mit, dass es über Änderungen (Verbindungsstatus, empfangene Daten usw.), die auf einer bestimmten Menge von Sockets auftreten, informiert werden möchte. Es ist dann Sache des Betriebssystems, sich um die Verwaltung der Verbindungen zu kümmern. Das Betriebssystem selbst kann einen oder mehrere Threads erstellen, um das zu erreichen, aber das geht uns nichts an. (Und es wird sicherlich keinen Thread für jede Verbindung erstellen.)

Für andere Arten von Operationen wie Aufrufe an C-Bibliotheken, die rechenintensiv sein können (z. B. Krypto), stellt libuv einen -Threadpool zur Verfügung, auf dem diese Operationen ausgeführt werden können. Da es sich um einen Threadpool handelt, müssen Sie sich auch nicht darum sorgen, dass die Threadanzahl ohne Einschränkung wächst. Wenn der Pool voll belegt ist, werden Vorgänge in die Warteschlange gestellt.

Ja, JavaScript wird in einem einzelnen Thread ausgeführt. Ja, Knoten (via libuv) erzeugt viele Threads im Hintergrund, um Arbeit zu leisten, damit der JavaScript-Thread nicht blockiert werden muss. Die Anzahl der Threads wird jedoch immer kontrolliert, und I / O erhält im Allgemeinen nicht einmal einen eigenen Knoten-zugewiesenen Thread, da dies vom Betriebssystem erledigt wird.

    
josh3736 31.01.2014, 19:04
quelle
4

Alles klar, lasst uns das ein bisschen durchbrechen. Single-Thread-Anwendungen haben Vorteile: Sie können niemals Deadlocks oder Race Conditions bekommen. Diese Probleme ergeben sich aus dem gleichzeitigen Speicherzugriff in Systemen mit mehreren Threads. Wenn zwei Threads auf dieselbe Information zugreifen, können seltsame Dinge passieren.

Warum hat JavaScript also Arbeiter? Wenn Sie eine schwere Verarbeitung durchführen müssen, blockieren Sie die Ereignisschleife. Sie könnten versuchen, die Arbeitslast durch Erzeugen von Timer-Ereignissen zu teilen, aber das ist mühsam. Ein Worker ermöglicht das Erstellen eines Threads unter einer Bedingung: Kein gemeinsamer Speicherzugriff . Dies löst das Problem der starken Verarbeitung in einer einzelnen Threaded-Umgebung und vermeidet gleichzeitig die Fallstricke von Multi-Threaded-Umgebungen (Deadlocks, Race-Conditions).

Und wie @dandavis sagte, wenn Sie eine Multi-Core-CPU haben (was heutzutage jeder tut), können die Worker-Threads auf die anderen Kerne ausgelagert werden.

Sie müssen sich darüber im Klaren sein, dass obwohl JavaScript ein Singlethread ist, die Umgebung immer noch sehr viel Multi-Threading aufweist. Das Lesen einer Datei ist in Node.JS nicht blockierend, aber es gibt wahrscheinlich einen Thread, der sie im Betriebssystem unterstützt.

Als kleinen Nachtrag würde ich sagen, dass der größte Vorteil von Node.JS darin besteht, dass Sie JavaScript auf dem Server schreiben können, wodurch Sie Code zwischen dem Client und dem Server freigeben können. Die Tatsache, dass es nicht blockierend ist, ist nett, aber Threads lösen das schon. Das nicht blockierende IO stammt aus der single thread-ness. Es ist sehr unpraktisch, einen einzigen Thread mit IO zu blockieren.

    
Halcyon 31.01.2014 17:11
quelle
1

Die Tatsache, dass Node.js keinen neuen Thread für die Verarbeitung jeder Webanforderung erstellen muss, ist ein Vorteil in Umgebungen, in denen Sie eine sehr große Anzahl gleichzeitiger Verbindungen haben (wie in Tausend oder Zehntausenden von gleichzeitigen Verbindungen). Darunter werden Sie wahrscheinlich keinen signifikanten Unterschied zu einer Thread-Umgebung wie Java / Apache oder C # / IIS sehen, da diese Plattformen heutzutage sehr gut optimiert sind.

Der Vorteil ist, dass selbst wenn Node.js einen neuen Thread für E / A-Operationen erstellen sollte (was in bestimmten Fällen nicht aber in anderen Fällen der Fall ist), Sie immer noch die Anzahl der benötigten Threads reduzieren 1-pro-Anfrage an 1. Noch einmal, wenn Sie Tausende von gleichzeitigen Verbindungen verarbeiten, ist das ein großer Gewinn.

    
Hector Correa 31.01.2014 18:29
quelle

Tags und Links