Inhaltsverzeichnis
Einige asynchrone E/A belegen zusätzliche Threads
Ist der Cluster multithreaded?
Richtig – Node-Multithreading
worker_thread 模块" >worker_thread 模块
多进程 vs 多线程
Heim Web-Frontend js-Tutorial Eine kurze Diskussion über Multithread-Operationen in Nodejs

Eine kurze Diskussion über Multithread-Operationen in Nodejs

Jun 23, 2021 am 10:31 AM
nodejs 多线程

Obwohl nodejs Single-Threaded ist, ermöglicht es dennoch Multithread-Operationen. Dieser Artikel beginnt mit Node-Threads, spricht über Multithread-Operationen in Nodejs und stellt die worker_threads-Vorlage vor.

Eine kurze Diskussion über Multithread-Operationen in Nodejs

Die Testumgebung für diesen Artikel:
System: macOS Mojave 10.14.2
CPU: 4 Kerne 2,3 GHz
Knoten: 10.15.1

[Empfohlenes Lernen: „nodejs-Tutorial“]

Apropos Node-Threads

Die meisten Leute verstehen, dass Node Single-Threaded ist, daher sollte die Anzahl der Threads nach dem Start von Node 1 sein. Lassen Sie uns ein Experiment durchführen, um das zu sehen. [Empfohlenes Lernen: „nodejs-Tutorial“]

setInterval(() => {
  console.log(new Date().getTime())
}, 3000)
Nach dem Login kopieren

Eine kurze Diskussion über Multithread-Operationen in Nodejs

Sie können sehen, dass der Node-Prozess 7 Threads belegt. Warum gibt es 7 Threads?

Wir alle wissen, dass der Kern von Node die v8-Engine ist. Nach dem Start von Node wird eine Instanz von v8 erstellt.

  • Hauptthread: Code kompilieren und ausführen.
  • Kompilierungs-/Optimierungsthread: Wenn der Hauptthread ausgeführt wird, kann der Code optimiert werden.
  • Analysator-Thread: zeichnet die Codelaufzeit auf und analysiert sie, um eine Grundlage für die Optimierung der Codeausführung durch Crankshaft zu schaffen.
  • Mehrere Threads zur Müllsammlung.

Wenn also oft gesagt wird, dass Node ein Single-Thread ist, bedeutet dies, dass die Ausführung von JavaScript Single-Thread ist, die Host-Umgebung von Javascript jedoch, egal ob Node oder Browser, Multi-Thread ist.

Node verfügt über zwei Compiler:
Full-Codegen: Kompilieren Sie js einfach und schnell in einfachen, aber langsamen mechanischen Code.
Crankshaft: Ein relativ komplexer Echtzeit-Optimierungscompiler, der leistungsstarken ausführbaren Code kompiliert.

Einige asynchrone E/A belegen zusätzliche Threads

Im obigen Beispiel lesen wir eine Datei, während der Timer ausgeführt wird:

const fs = require('fs')

setInterval(() => {
    console.log(new Date().getTime())
}, 3000)

fs.readFile('./index.html', () => {})
Nach dem Login kopieren

Eine kurze Diskussion über Multithread-Operationen in Nodejs

Die Anzahl der Threads beträgt 11, das liegt daran, dass es einige E/A gibt Vorgänge (DNS, FS) und einige CPU-intensive Berechnungen (Zlib, Crypto) in Node, Nodes Thread-Pool wird aktiviert und die Standardgröße des Thread-Pools beträgt 4, da die Anzahl der Threads 11 beträgt.

Wir können die Standardgröße des Thread-Pools manuell ändern:

process.env.UV_THREADPOOL_SIZE = 64
Nach dem Login kopieren

Ändern Sie die Threads mit einer Codezeile ganz einfach auf 71.

Eine kurze Diskussion über Multithread-Operationen in Nodejs

Ist der Cluster multithreaded?

Der einzelne Thread von Node bringt auch einige Probleme mit sich, z. B. eine unzureichende Auslastung der CPU, eine nicht abgefangene Ausnahme kann dazu führen, dass das gesamte Programm beendet wird usw. Da das Clustermodul in Node bereitgestellt wird, implementiert der Cluster die Kapselung von child_process und implementiert das Multiprozessmodell, indem untergeordnete Prozesse über die Fork-Methode erstellt werden. Beispielsweise ist pm2, das wir am häufigsten verwenden, der beste Vertreter unter ihnen.

Sehen wir uns eine Cluster-Demo an:

const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  console.log(`主进程 ${process.pid} 正在运行`);
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on(&#39;exit&#39;, (worker, code, signal) => {
    console.log(`工作进程 ${worker.process.pid} 已退出`);
  });
} else {
  // 工作进程可以共享任何 TCP 连接。
  // 在本例子中,共享的是 HTTP 服务器。
  http.createServer((req, res) => {
    res.writeHead(200);
    res.end(&#39;Hello World&#39;);
  }).listen(8000);
  console.log(`工作进程 ${process.pid} 已启动`);
}
Nach dem Login kopieren

Sehen Sie sich zu diesem Zeitpunkt den Aktivitätsmonitor an:

Eine kurze Diskussion über Multithread-Operationen in Nodejs

Es gibt insgesamt 9 Prozesse, einer davon ist der Hauptprozess, die Anzahl der CPUs x die Anzahl der CPUs Kerne = 2 x 4 = 8 Teilprozesse verarbeiten.

Also ist weder child_process noch Cluster ein Multi-Thread-Modell, sondern ein Multi-Prozess-Modell. Obwohl Entwickler sich der Probleme des Single-Threaded-Modells bewusst sind, lösen sie das Problem nicht grundlegend und stellen eine Multiprozessmethode zur Simulation von Multithreading bereit. Aus den vorherigen Experimenten können wir erkennen, dass Node (V8) zwar selbst über Multithreading-Fähigkeiten verfügt, Entwickler diese Fähigkeit jedoch nicht sinnvoll nutzen können. Stattdessen nutzen sie Multithreading in gewisser Weise, das von der untersten Ebene von Node bereitgestellt wird. Node-Beamter sagte:

Sie können den integrierten Node-Worker-Pool verwenden, indem Sie ein C++-Add-on entwickeln. Erstellen Sie Ihr C++-Add-on mit NAN und verwenden Sie bei neueren Versionen N-API bietet eine reine JavaScript-Methode für den Zugriff auf den Worker-Pool von Node.

Aber für JavaScript-Entwickler gab es nie eine standardmäßige und benutzerfreundliche Möglichkeit, die Multithreading-Funktionen von Node zu nutzen.

Richtig – Node-Multithreading

Bis zur Veröffentlichung von Node 10.5.0 stellte der Beamte ein experimentelles Modul worker_threads zur Verfügung, um Node mit echten Multithreading-Funktionen auszustatten.

Werfen wir zunächst einen Blick auf die einfache Demo:

const {
  isMainThread,
  parentPort,
  workerData,
  threadId,
  MessageChannel,
  MessagePort,
  Worker
} = require(&#39;worker_threads&#39;);

function mainThread() {
  for (let i = 0; i < 5; i++) {
    const worker = new Worker(__filename, { workerData: i });
    worker.on(&#39;exit&#39;, code => { console.log(`main: worker stopped with exit code ${code}`); });
    worker.on(&#39;message&#39;, msg => {
      console.log(`main: receive ${msg}`);
      worker.postMessage(msg + 1);
    });
  }
}

function workerThread() {
  console.log(`worker: workerDate ${workerData}`);
  parentPort.on(&#39;message&#39;, msg => {
    console.log(`worker: receive ${msg}`);
  }),
  parentPort.postMessage(workerData);
}

if (isMainThread) {
  mainThread();
} else {
  workerThread();
}
Nach dem Login kopieren

Der obige Code öffnet fünf Unterthreads im Hauptthread und der Hauptthread sendet einfache Nachrichten an die Unterthreads.

由于 worker_thread 目前仍然处于实验阶段,所以启动时需要增加 --experimental-worker flag,运行后观察活动监视器:

Eine kurze Diskussion über Multithread-Operationen in Nodejs

不多不少,正好多了五个子线程。

worker_thread 模块

worker_thread 核心代码

worker_thread 模块中有 4 个对象和 2 个类。

  • isMainThread: 是否是主线程,源码中是通过 threadId === 0 进行判断的。
  • MessagePort: 用于线程之间的通信,继承自 EventEmitter。
  • MessageChannel: 用于创建异步、双向通信的通道实例。
  • threadId: 线程 ID。
  • Worker: 用于在主线程中创建子线程。第一个参数为 filename,表示子线程执行的入口。
  • parentPort: 在 worker 线程里是表示父进程的 MessagePort 类型的对象,在主线程里为 null
  • workerData: 用于在主进程中向子进程传递数据(data 副本)

来看一个进程通信的例子:

const assert = require(&#39;assert&#39;);
const {
  Worker,
  MessageChannel,
  MessagePort,
  isMainThread,
  parentPort
} = require(&#39;worker_threads&#39;);
if (isMainThread) {
  const worker = new Worker(__filename);
  const subChannel = new MessageChannel();
  worker.postMessage({ hereIsYourPort: subChannel.port1 }, [subChannel.port1]);
  subChannel.port2.on(&#39;message&#39;, (value) => {
    console.log(&#39;received:&#39;, value);
  });
} else {
  parentPort.once(&#39;message&#39;, (value) => {
    assert(value.hereIsYourPort instanceof MessagePort);
    value.hereIsYourPort.postMessage(&#39;the worker is sending this&#39;);
    value.hereIsYourPort.close();
  });
}
Nach dem Login kopieren

更多详细用法可以查看官方文档

多进程 vs 多线程

根据大学课本上的说法:“进程是资源分配的最小单位,线程是CPU调度的最小单位”,这句话应付考试就够了,但是在实际工作中,我们还是要根据需求合理选择。

下面对比一下多线程与多进程:

属性 多进程 多线程 比较
数据 数据共享复杂,需要用IPC;数据是分开的,同步简单 因为共享进程数据,数据共享简单,同步复杂 各有千秋
CPU、内存 占用内存多,切换复杂,CPU利用率低 占用内存少,切换简单,CPU利用率高 多线程更好
销毁、切换 创建销毁、切换复杂,速度慢 创建销毁、切换简单,速度很快 多线程更好
coding 编码简单、调试方便 编码、调试复杂 多进程更好
可靠性 进程独立运行,不会相互影响 线程同呼吸共命运 多进程更好
分布式 可用于多机多核分布式,易于扩展 只能用于多核分布式 多进程更好

上述比较仅表示一般情况,并不绝对。

work_thread 让 Node 有了真正的多线程能力,算是不小的进步。

更多编程相关知识,请访问:编程视频!!

Das obige ist der detaillierte Inhalt vonEine kurze Diskussion über Multithread-Operationen in Nodejs. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
2 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
Repo: Wie man Teamkollegen wiederbelebt
1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Abenteuer: Wie man riesige Samen bekommt
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

C++-Funktionsausnahmen und Multithreading: Fehlerbehandlung in gleichzeitigen Umgebungen C++-Funktionsausnahmen und Multithreading: Fehlerbehandlung in gleichzeitigen Umgebungen May 04, 2024 pm 04:42 PM

Die Behandlung von Funktionsausnahmen in C++ ist in Multithread-Umgebungen besonders wichtig, um Thread-Sicherheit und Datenintegrität sicherzustellen. Mit der try-catch-Anweisung können Sie bestimmte Arten von Ausnahmen abfangen und behandeln, wenn sie auftreten, um Programmabstürze oder Datenbeschädigungen zu verhindern.

Gibt es einen großen Unterschied zwischen NodeJS und Java? Gibt es einen großen Unterschied zwischen NodeJS und Java? Apr 21, 2024 am 06:12 AM

Die Hauptunterschiede zwischen Node.js und Java sind Design und Funktionen: Ereignisgesteuert vs. Thread-gesteuert: Node.js ist ereignisgesteuert und Java ist Thread-gesteuert. Single-Threaded vs. Multi-Threaded: Node.js verwendet eine Single-Threaded-Ereignisschleife und Java verwendet eine Multithread-Architektur. Laufzeitumgebung: Node.js läuft auf der V8-JavaScript-Engine, während Java auf der JVM läuft. Syntax: Node.js verwendet JavaScript-Syntax, während Java Java-Syntax verwendet. Zweck: Node.js eignet sich für I/O-intensive Aufgaben, während Java für große Unternehmensanwendungen geeignet ist.

Wie können Parallelität und Multithreading von Java-Funktionen die Leistung verbessern? Wie können Parallelität und Multithreading von Java-Funktionen die Leistung verbessern? Apr 26, 2024 pm 04:15 PM

Parallelitäts- und Multithreading-Techniken mithilfe von Java-Funktionen können die Anwendungsleistung verbessern, einschließlich der folgenden Schritte: Parallelitäts- und Multithreading-Konzepte verstehen. Nutzen Sie die Parallelitäts- und Multithreading-Bibliotheken von Java wie ExecutorService und Callable. Üben Sie Fälle wie die Multithread-Matrixmultiplikation, um die Ausführungszeit erheblich zu verkürzen. Genießen Sie die Vorteile einer erhöhten Reaktionsgeschwindigkeit der Anwendung und einer optimierten Verarbeitungseffizienz durch Parallelität und Multithreading.

So verbinden Sie NodeJS mit der MySQL-Datenbank So verbinden Sie NodeJS mit der MySQL-Datenbank Apr 21, 2024 am 06:13 AM

Um eine Verbindung zu einer MySQL-Datenbank herzustellen, müssen Sie die folgenden Schritte ausführen: Installieren Sie den MySQL2-Treiber. Verwenden Sie mysql2.createConnection(), um ein Verbindungsobjekt zu erstellen, das die Hostadresse, den Port, den Benutzernamen, das Passwort und den Datenbanknamen enthält. Verwenden Sie „connection.query()“, um Abfragen durchzuführen. Verwenden Sie abschließend Connection.end(), um die Verbindung zu beenden.

Wie implementiert man Multithreading in PHP? Wie implementiert man Multithreading in PHP? May 06, 2024 pm 09:54 PM

PHP-Multithreading bezieht sich auf die gleichzeitige Ausführung mehrerer Aufgaben in einem Prozess, was durch die Erstellung unabhängig laufender Threads erreicht wird. Sie können die Pthreads-Erweiterung in PHP verwenden, um Multithreading-Verhalten zu simulieren. Nach der Installation können Sie die Thread-Klasse zum Erstellen und Starten von Threads verwenden. Wenn beispielsweise eine große Datenmenge verarbeitet wird, können die Daten in mehrere Blöcke unterteilt und eine entsprechende Anzahl von Threads erstellt werden, um sie gleichzeitig zu verarbeiten, um die Effizienz zu verbessern.

Wie gehe ich mit gemeinsam genutzten Ressourcen beim Multithreading in C++ um? Wie gehe ich mit gemeinsam genutzten Ressourcen beim Multithreading in C++ um? Jun 03, 2024 am 10:28 AM

Mutexe werden in C++ verwendet, um gemeinsam genutzte Multithread-Ressourcen zu verarbeiten: Erstellen Sie Mutexe über std::mutex. Verwenden Sie mtx.lock(), um einen Mutex zu erhalten und exklusiven Zugriff auf gemeinsam genutzte Ressourcen bereitzustellen. Verwenden Sie mtx.unlock(), um den Mutex freizugeben.

Herausforderungen und Gegenmaßnahmen der C++-Speicherverwaltung in Multithread-Umgebungen? Herausforderungen und Gegenmaßnahmen der C++-Speicherverwaltung in Multithread-Umgebungen? Jun 05, 2024 pm 01:08 PM

In einer Multithread-Umgebung steht die C++-Speicherverwaltung vor den folgenden Herausforderungen: Datenrennen, Deadlocks und Speicherlecks. Zu den Gegenmaßnahmen gehören: 1. Verwendung von Synchronisationsmechanismen, wie Mutexe und atomare Variablen; 3. Verwendung von intelligenten Zeigern; 4. Implementierung von Garbage Collection;

Welche Beziehung besteht zwischen NodeJS und NPM? Welche Beziehung besteht zwischen NodeJS und NPM? Apr 21, 2024 am 06:09 AM

Node.js ist eine JavaScript-Laufzeitumgebung und npm ist ihr Paketmanager. Die beiden arbeiten zusammen, um Entwicklern das Schreiben serverseitiger Programme in JavaScript, die Verwendung von Modulen von Drittanbietern und die einfache Verwaltung von Modulen zu ermöglichen.

See all articles