348 Stimmen

Wie das single threaded non blocking IO-Modell in Node.js funktioniert

Ich bin kein Node-Programmierer, aber ich bin daran interessiert, wie das single-threaded nicht-blockierende IO-Modell funktioniert. Nachdem ich den Artikel gelesen habe verstehen-der-knoten-js-event-schleife Ich bin wirklich verwirrt. Es gab ein Beispiel für das Modell:

c.query(
   'SELECT SLEEP(20);',
   function (err, results, fields) {
     if (err) {
       throw err;
     }
     res.writeHead(200, {'Content-Type': 'text/html'});
     res.end('<html><head><title>Hello</title></head><body><h1>Return from async DB query</h1></body></html>');
     c.end();
    }
);

Que: Wenn es zwei Anfragen A (kommt zuerst) und B gibt, da es nur einen einzigen Thread gibt, wird das serverseitige Programm zuerst die Anfrage A bearbeiten: die SQL-Abfrage ist eine schlafende Anweisung, die für I/O-Warten steht. Und das Programm bleibt bei der I/O und kann den Code, der die Webseite rendert, nicht ausführen. Wird das Programm während der Wartezeit zu Anforderung B wechseln? Meiner Meinung nach gibt es aufgrund des Single-Thread-Modells keine Möglichkeit, eine Anforderung von einer anderen zu trennen. Aber der Titel des Beispielcodes sagt, dass alles läuft parallel, außer Ihrem Code .

(P.S. Ich bin mir nicht sicher, ob ich den Code falsch verstanden habe, da ich Wie kann Node während des Wartens von A nach B wechseln? Und können Sie erklären das single-threaded nicht-blockierende IO-Modell eines Knotens in einer einfache Art und Weise? Ich würde es zu schätzen wissen, wenn Sie mir helfen könnten :)

3voto

Gal Ben-Haim Punkte 17273

Wenn Sie ein wenig weiter lesen - "Natürlich gibt es im Backend Threads und Prozesse für den DB-Zugriff und die Prozessausführung. Diese sind jedoch nicht explizit für Ihren Code sichtbar, so dass Sie sich keine Gedanken darüber machen können, außer dass Sie wissen, dass E/A-Interaktionen z. B. mit der Datenbank oder mit anderen Prozessen aus der Perspektive jeder Anfrage asynchron sind, da die Ergebnisse aus diesen Threads über die Ereignisschleife an Ihren Code zurückgegeben werden."

über - "alles läuft parallel, außer Ihrem Code" - Ihr Code wird synchron ausgeführt, wann immer Sie eine asynchrone Operation aufrufen, wie z. B. Warten auf IO, die Ereignisschleife behandelt alles und ruft den Rückruf auf. es ist einfach nicht etwas, worüber Sie nachdenken müssen.

in Ihrem Beispiel: es gibt zwei Anfragen A (kommt zuerst) und B. Sie führen Anfrage A aus, Ihr Code läuft synchron weiter und führt Anfrage B aus. die Ereignisschleife verarbeitet Anfrage A, wenn sie fertig ist, ruft sie den Callback von Anfrage A mit dem Ergebnis auf, dasselbe gilt für Anfrage B.

1voto

Robert Siemer Punkte 28819

Okay, die meisten Dinge sollten soweit klar sein... der knifflige Teil ist das SQL wenn es nicht in Wirklichkeit ist in einem anderen Thread oder Prozess laufen in ihrer Gesamtheit, muss die SQL-Ausführung aufgeschlüsselt in einzelne Schritte (von einem SQL-Prozessor, der für die asynchrone Ausführung konzipiert ist!), wobei die nicht blockierenden ausgeführt werden und die blockierenden (z. B. der Schlaf) tatsächlich puede an den Kernel (als Alarm-Interrupt/Ereignis) übertragen und in die Ereignisliste für die Hauptschleife aufgenommen werden.

Das bedeutet, dass z.B. die Interpretation des SQL, etc. sofort erfolgt, aber während des Wartens (gespeichert als ein Ereignis in der Zukunft durch den Kernel in einer kqueue, epoll, ... Struktur; zusammen mit den anderen IO-Operationen) kann die Hauptschleife andere Dinge tun und schließlich überprüfen, ob etwas von diesen IOs und Wartezeiten passiert ist.

Um es noch einmal zu sagen: Das Programm bleibt nie stecken, schlafende Aufrufe werden nie ausgeführt. Ihre Aufgabe wird vom Kernel (etwas schreiben, warten, dass etwas über das Netzwerk kommt, warten, dass die Zeit vergeht) oder einem anderen Thread oder Prozess übernommen. - Der Node-Prozess prüft in jedem Event-Loop-Zyklus, ob mindestens eine dieser Aufgaben durch den Kernel im einzigen blockierenden Aufruf an das Betriebssystem erledigt wurde. Dieser Punkt ist erreicht, wenn alles, was nicht blockiert, erledigt ist.

Klar? :-)

Ich kenne Node nicht. Aber woher kommt die c.query?

0voto

Yilmaz Punkte 12859

En event loop ermöglicht es Node.js, nicht-blockierende E/A-Operationen durchzuführen - trotz der Tatsache, dass JavaScript single-threaded ist - indem es Operationen, wann immer möglich, an den Systemkern auslagert. Man denke an event loop als Manager.

  • Neue Anfragen werden in eine Warteschlange gestellt und von der synchronous event demultiplexer . Wie Sie sehen, wird jeder Operationshandler auch registriert.

enter image description here

  • Anschließend werden diese Anfragen synchron an den Thread-Pool (Worker Pool) gesendet, um ausgeführt zu werden. JavaScript kann keine asynchronen E/A-Operationen durchführen. In der Browserumgebung führt der Browser die asynchronen Operationen aus. In der Node-Umgebung werden asynchrone Operationen von der libuv durch die Verwendung von C++ . Die Standardgröße des Thread-Pools ist 4, aber sie kann beim Start geändert werden, indem man die UV_THREADPOOL_SIZE Umgebungsvariable auf einen beliebigen Wert (maximal 128). Thread-Pool-Größe 4 bedeutet, dass 4 Anfragen gleichzeitig ausgeführt werden können, wenn der Ereignis-Demultiplexer 5 Anfragen hat, würden 4 an den Thread-Pool weitergeleitet werden und die fünfte würde warten. Sobald jede Anforderung ausgeführt wurde,

enter image description here

  • W

enter image description here

h

0voto

Animir Punkte 1086

F

N

Y

I

I E , W y t .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X