


Wie man versteht, dass Node.js kein vollständig Single-Threaded-Programm ist (eine kurze Analyse)
Warum sagen wir, dass Node.js nicht vollständig Single-Threaded ist? Wie ist das zu verstehen? Der folgende Artikel wird mit Ihnen darüber diskutieren, ich hoffe, er wird Ihnen hilfreich sein!
Ich glaube, jeder weiß, dass node ein Single-Thread-Programm ist, das Event Loop verwendet, um mehrere Parallelitäten zu erreichen. Leider ist das nicht ganz richtig.
Warum ist Node.js kein vollständig Single-Threaded-Programm?
Node.js ist ein Single-Thread-Programm*
Alle Javsacript-, V8- und Event-Schleifen, die wir selbst geschrieben haben, laufen im selben Thread, dem Haupt-Thrad.
Hey, bedeutet das nicht, dass der Knoten Single-Threaded ist?
Aber vielleicht wissen Sie nicht, dass Node viele Module mit C++-Code dahinter hat.
Obwohl Node Benutzern nicht die Berechtigung zur Steuerung von Threads erteilt, kann C++ Multithreading verwenden.
Wann wird der Knoten Multithreading verwenden?
Wenn eine Knotenmethode hinter den Kulissen die synchronization-Methode von C++ aufruft, wird alles im Hauptthread ausgeführt.
Wenn eine Knotenmethode hinter den Kulissen die asynchrone-Methode von C++ aufruft, wird sie manchmal nicht im Hauptthread ausgeführt.
Talk ist günstig, zeig mir den Code
Synchrone Methode, läuft im Hauptthread
Hier crypto
Verwandte Module, viele sind in C++ geschrieben. Das folgende Programm ist eine Funktion zur Hash-Berechnung, die im Allgemeinen zum Speichern von Passwörtern verwendet wird.
import { pbkdf2Sync } from "crypto"; const startTime = Date.now(); let index = 0; for (index = 0; index < 3; index++) { pbkdf2Sync("secret", "salt", 100000, 64, "sha512"); const endTime = Date.now(); console.log(`${index} time, ${endTime - startTime}`); } const endTime = Date.now(); console.log(`in the end`);
Ausgabezeit,
0 time, 44 1 time, 90 2 time, 134 in the end
Es ist ersichtlich, dass es jedes Mal etwa 45 ms dauert und der Code sequentiell im Hauptthread ausgeführt wird.
Achten Sie darauf, wer die endgültige Ausgabe ist? Beachten Sie, dass ein Hash hier auf meiner CPU ca. 45 ms dauert.
Die asynchrone pbkdf2-Methode wird nicht im Hauptthread ausgeführt
import { cpus } from "os"; import { pbkdf2 } from "crypto"; console.log(cpus().length); let startTime = console.time("time-main-end"); for (let index = 0; index < 4; index++) { startTime = console.time(`time-${index}`); pbkdf2("secret", `salt${index}`, 100000, 64, "sha512", (err, derivedKey) => { if (err) throw err; console.timeEnd(`time-${index}`); }); } console.timeEnd("time-main-end");
Die Ausgabezeit,
time-main-end: 0.31ms time-2: 45.646ms time-0: 46.055ms time-3: 46.846ms time-1: 47.159ms
Wie Sie hier sehen können, endet der Hauptthread früh, aber jede Berechnungszeit beträgt 45 ms. Sie müssen wissen, dass a Die CPU berechnet den Hash. Die Zeit beträgt 45 ms. Der Knoten verwendet hier definitiv mehrere Threads für die Hash-Berechnung.
Wenn ich hier die Anzahl der Aufrufe auf 10 ändere, dann ist die Zeit wie folgt. Sie können sehen, dass mit zunehmender Anzahl der CPU-Kerne auch die Zeit zunimmt. Wieder einmal wurde bewiesen, dass der Knoten definitiv mehrere Threads für die Hash-Berechnung verwendet.
time-main-end: 0.451ms time-1: 44.977ms time-2: 46.069ms time-3: 50.033ms time-0: 51.381ms time-5: 96.429ms // 注意这里,从第五次时间开始增加了 time-7: 101.61ms time-4: 113.535ms time-6: 121.429ms time-9: 151.035ms time-8: 152.585ms
Obwohl hier bewiesen ist, dass auf dem Knoten definitiv Multithreading aktiviert ist. Aber ein kleines Problem? Die CPU meines Computers ist AMD R5-5600U, die über 6 Kerne und 12 Threads verfügt. Aber warum verlängert sich die Zeit ab dem fünften Mal? Node nutzt meine CPU nicht vollständig aus?
Was ist der Grund?
Knoten verwendet einen vordefinierten Thread-Pool.
export UV_THREADPOOL_SIZE=6
Schauen wir uns ein Beispiel an:
HTTP-Anfrage
import { request } from "https"; const options = { hostname: "www.baidu.com", port: 443, path: "/img/PC_7ac6a6d319ba4ae29b38e5e4280e9122.png", method: "GET", }; let startTime = console.time(`main`); for (let index = 0; index < 15; index++) { startTime = console.time(`time-${index}`); const req = request(options, (res) => { console.log(`statusCode: ${res.statusCode}`); console.timeEnd(`time-${index}`); res.on("data", (d) => { // process.stdout.write(d); }); }); req.on("error", (error) => { console.error(error); }); req.end(); } console.timeEnd("main");
main: 13.927ms time-2: 83.247ms time-4: 89.641ms time-3: 91.497ms time-12: 91.661ms time-5: 94.677ms ..... time-8: 134.026ms time-1: 143.906ms time-13: 140.914ms time-10: 144.088ms
Das Hauptprogramm hier ist Auch hier endete die HTTP-Anfrage zum Herunterladen von Bildern 15 Mal. Die Zeit, die sie brauchten, erhöhte sich nicht exponentiell und schien nicht durch den Thread-Pool/die CPU begrenzt zu sein.
Warum? ? Verwendet Node einen Thread-Pool?
Wenn die C++-Methode asynchronous hinter Node steht, wird zunächst versucht, festzustellen, ob Kernel-Asynchronitätsunterstützung vorhanden ist. Bitte verwenden Sie hier epoll (Linux) für das Netzwerk. Wenn der Kernel keine asynchrone Methode bereitstellt, Node wird seinen eigenen Thread-Pool verwenden. .
Obwohl die HTTP-Anforderung asynchron ist, wird sie vom Kernel implementiert. Wenn der Kernel abgeschlossen ist, wird C++ benachrichtigt und C++ benachrichtigt den Hauptthread, um den Rückruf zu verarbeiten.
Welche asynchronen Methoden in Node verwenden also den Thread-Pool? Welche nicht?
-
Native Kernal Async
- TCP/UDP-Server-Client
- Unix Domain Sockets (IPC)
- pipes
- dns.resolveXXX
- tty-Eingabe (stdin usw.)
- Unix. Signale
- Untergeordnete Prozess
-
Thread-Pool
- fs.*
- dns.lookup
- pipe (Edge-Fall)
Dies ist auch der Einstiegspunkt für die meisten Knotenoptimierungen.
Aber wie lassen sich diese mit dem wichtigsten Event Loop kombinieren?
Event Loop
Ich glaube, jeder ist mit Event Loop bestens vertraut. Die Ereignisschleife ist wie ein Verteiler.
Wenn sie auf ein gewöhnliches Javascript-Programm oder einen Rückruf trifft, wird sie zur Verarbeitung an V8 übergeben.
Wenn Sie auf eine in C++ geschriebene synchronisierte Methode stoßen, übergeben Sie sie an C++ und führen Sie sie im Hauptthread aus.
Wenn Sie auf eine asynchrone-Methode stoßen, ist die Rückseite in C++ geschrieben. Wenn Kernel-Asynchronitätsunterstützung vorhanden ist, übergeben Sie sie vom Hauptthread an den Kernel zur Verarbeitung.
Wenn es asynchron ist, wird die Rückseite der Methode in C++ geschrieben. Wenn keine asynchrone Kernelunterstützung vorhanden ist, wird sie vom Hauptthread an den Thread-Pool übergeben.
- Der Thread-Pool und der Kernel geben die Ergebnisse an die Ereignisschleife zurück. Wenn ein Javascript-Rückruf registriert ist, wird dieser zur Verarbeitung an V8 übergeben.
Dann geht der Zyklus weiter, bis nichts mehr zu verarbeiten ist.
Node ist also nicht gerade ein Single-Threaded-Programm.
Weitere Informationen zu Knoten finden Sie unter: nodejs-Tutorial!
Das obige ist der detaillierte Inhalt vonWie man versteht, dass Node.js kein vollständig Single-Threaded-Programm ist (eine kurze Analyse). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

Der nicht blockierende und ereignisgesteuerte Knotendienst hat den Vorteil eines geringen Speicherverbrauchs und eignet sich sehr gut für die Verarbeitung massiver Netzwerkanforderungen. Unter der Voraussetzung massiver Anfragen müssen Probleme im Zusammenhang mit der „Speicherkontrolle“ berücksichtigt werden. 1. Der Garbage-Collection-Mechanismus und die Speicherbeschränkungen von V8 Js wird von der Garbage-Collection-Maschine gesteuert

Dieser Artikel vermittelt Ihnen ein detailliertes Verständnis des Speichers und Garbage Collectors (GC) der NodeJS V8-Engine. Ich hoffe, er wird Ihnen hilfreich sein!

Node 19 wurde offiziell veröffentlicht. Dieser Artikel wird Ihnen eine detaillierte Erklärung der 6 Hauptfunktionen von Node.js 19 geben. Ich hoffe, er wird Ihnen hilfreich sein!

Das Dateimodul ist eine Kapselung der zugrunde liegenden Dateioperationen, wie z. B. Lesen/Schreiben/Öffnen/Schließen/Löschen von Dateien, Hinzufügen usw. Das größte Merkmal des Dateimoduls besteht darin, dass alle Methoden zwei Versionen von **synchronem** und **bereitstellen. asynchron**, mit Methoden mit dem Suffix sync sind alle Synchronisationsmethoden, und diejenigen ohne sind alle heterogene Methoden.

Die Auswahl eines Docker-Images für Node mag trivial erscheinen, aber die Größe und potenziellen Schwachstellen des Images können erhebliche Auswirkungen auf Ihren CI/CD-Prozess und Ihre Sicherheit haben. Wie wählen wir also das beste Node.js-Docker-Image aus?

Der Grund, warum der Knoten den Befehl npm nicht verwenden kann, liegt darin, dass die Umgebungsvariablen nicht richtig konfiguriert sind. Die Lösung ist: 1. Öffnen Sie „Systemeigenschaften“ 2. Suchen Sie nach „Umgebungsvariablen“ -> „Systemvariablen“ und bearbeiten Sie dann die Umgebung Variablen; 3. Suchen Sie den Speicherort des NodeJS-Ordners. 4. Klicken Sie auf „OK“.

Wie führt Node.js GC (Garbage Collection) durch? Der folgende Artikel führt Sie durch.

Die Ereignisschleife ist ein grundlegender Bestandteil von Node.js und ermöglicht die asynchrone Programmierung, indem sie sicherstellt, dass der Hauptthread nicht blockiert wird. Das Verständnis der Ereignisschleife ist für die Erstellung effizienter Anwendungen von entscheidender Bedeutung. Der folgende Artikel wird Ihnen ein detailliertes Verständnis der Ereignisschleife in Node vermitteln. Ich hoffe, er wird Ihnen hilfreich sein!
