EinführungDie Hauptereignisschleife von nodejs ist einfädig. Nodejs selbst unterhält auch einen Worker-Pool, um einige zeitaufwändige Vorgänge abzuwickeln. Wir können auch manuell neue Threads erstellen, um unsere eigenen Aufgaben auszuführen, indem wir die von nodejs bereitgestellten worker_threads verwenden. Dieser Artikel stellt eine neue Möglichkeit zur Ausführung von Node.JS-Aufgaben und untergeordneten Prozessen vor. Untergeordneter Prozesslib/child_process.js stellt das Modul child_process bereit, mit dem wir untergeordnete Prozesse erstellen können. Beachten Sie, dass worker_threads untergeordnete Threads erstellt, während child_process untergeordnete Prozesse erstellt. Im Modul child_process können Prozesse synchron oder asynchron erstellt werden. Die synchrone Erstellungsmethode besteht lediglich darin, Sync nach der asynchronen Erstellungsmethode hinzuzufügen. Der erstellte Prozess wird durch die Klasse ChildProcess dargestellt. Schauen wir uns die Definition von ChildProcess an: Schnittstelle ChildProcess erweitert events.EventEmitter { stdin: Beschreibbar | null; stdout: Lesbar | null; stderr: Lesbar | null; schreibgeschützter Kanal?: Pipe | null; schreibgeschütztes stdio: [ Schreibbar | null, // stdin Lesbar | null, // stdout Lesbar | null, // stderr Lesbar | Schreibbar | null | undefiniert, // extra Lesbar | Schreibbar | null | undefiniert // extra ]; schreibgeschützt beendet: Boolesch; schreibgeschützte PID: Nummer; schreibgeschützt verbunden: Boolesch; schreibgeschützter ExitCode: Zahl | null; schreibgeschützter Signalcode: NodeJS.Signals | null; schreibgeschützte Spawnargs: Zeichenfolge[]; schreibgeschützte Spawndatei: Zeichenfolge; kill(Signal?: NodeJS.Signals | Zahl): Boolesch; senden (Nachricht: Serialisierbar, Rückruf?: (Fehler: Fehler | null) => void): Boolesch; senden (Nachricht: Serialisierbar, Sendehandle?: Sendehandle, Rückruf?: (Fehler: Fehler | null) => ungültig): Boolesch; senden (Nachricht: Serialisierbar, Sende-Handle?: Sende-Handle, Optionen?: Nachrichtenoptionen, Rückruf?: (Fehler: Fehler | null) => ungültig): Boolesch; trennen(): void; unref(): ungültig; ref(): ungültig; /** * Ereignisse.EventEmitter * 1. schließen * 2. trennen * 3. Fehler * 4. Ausgang * 5. Nachricht */ ... } Sie können sehen, dass ChildProcess auch ein EventEmitter ist und daher Ereignisse senden und empfangen kann. ChildProcess kann fünf Ereignistypen empfangen: Schließen, Trennen, Fehler, Beenden und Nachricht. Das Trennungsereignis wird ausgelöst, wenn im übergeordneten Prozess subprocess.disconnect() oder im untergeordneten Prozess process.disconnect() aufgerufen wird. Das Fehlerereignis wird ausgelöst, wenn ein Prozess nicht erstellt oder beendet werden kann oder an einen untergeordneten Prozess keine Nachricht gesendet werden kann. Wenn der Kindprozess endet, wird das Exit-Ereignis ausgelöst. Das Schließereignis wird ausgelöst, wenn die Standarddio-Streams des untergeordneten Prozesses geschlossen werden. Beachten Sie, dass sich das Schließereignis vom Beendigungsereignis unterscheidet, da mehrere Prozesse möglicherweise dasselbe Standarddio gemeinsam nutzen, sodass das Senden eines Beendigungsereignisses nicht unbedingt ein Schließereignis auslöst. Schauen wir uns ein Beispiel für Schließen und Beenden an: const { spawn } = erfordern('Kindprozess'); const ls = spawn('ls', ['-lh', '/usr']); ls.stdout.on('Daten', (Daten) => { Konsole.log(`stdout: ${data}`); }); ls.on('schließen', (Code) => { console.log(`Der untergeordnete Prozess verwendet den Code $[code], um alle Standarddio zu schließen`); }); ls.on('exit', (Code) => { console.log(`Der untergeordnete Prozess wurde mit dem Code $[code] beendet`); }); Schließlich gibt es das Nachrichtenereignis, das ausgelöst wird, wenn der untergeordnete Prozess mit process.send() eine Nachricht sendet. Es gibt mehrere Standard-Stream-Attribute in ChildProcess, nämlich stderr, stdout, stdin und stdio. stderr, stdout und stdin sind leicht zu verstehen, sie stehen jeweils für Standardfehler, Standardausgabe und Standardeingabe. Schauen wir uns die Verwendung von stdout an: const { spawn } = erfordern('Kindprozess'); const subprocess = spawn('ls'); subprocess.stdout.on('Daten', (Daten) => { console.log(`Empfangener Datenblock ${data}`); }); stdio ist eigentlich eine Sammlung von stderr, stdout und stdin: schreibgeschütztes stdio: [ Schreibbar | null, // stdin Lesbar | null, // stdout Lesbar | null, // stderr Lesbar | Schreibbar | null | undefiniert, // extra Lesbar | Schreibbar | null | undefiniert // extra ]; Davon steht stdio[0] für stdin, stdio[1] für stdout und stdio[2] für stderr. Wenn die drei Standard-Streams beim Erstellen des untergeordneten Prozesses mit stdio auf etwas anderes als Pipe eingestellt sind, sind stdin, stdout und stderr null. Sehen wir uns ein Beispiel mit stdio an: const assert = erfordern('assert'); const fs = erfordern('fs'); const untergeordneter Prozess = erforderlich('untergeordneter Prozess'); const Unterprozess = Kindprozess.spawn('ls', { stdio: 0, // Standardeingabe des übergeordneten Prozesses für untergeordneten Prozess verwenden. „Pipe“, // Übergeben Sie die Standardausgabe des untergeordneten Prozesses über die Pipe an den übergeordneten Prozess. fs.openSync('err.out', 'w') // Leitet den stderr des untergeordneten Prozesses in eine Datei um. ] }); assert.strictEqual(subprocess.stdio[0], null); assert.strictEqual(Unterprozess.stdio[0], Unterprozess.stdin); assert(Unterprozess.stdout); assert.strictEqual(Unterprozess.stdio[1], Unterprozess.stdout); assert.strictEqual(subprocess.stdio[2], null); assert.strictEqual(Unterprozess.stdio[2], Unterprozess.stderr); Normalerweise verwaltet der übergeordnete Prozess einen Referenzzähler für den untergeordneten Prozess und der übergeordnete Prozess wird erst beendet, wenn der untergeordnete Prozess beendet wird. Diese Referenz ist „ref“, und wenn die Methode „unref“ aufgerufen wird, ermöglicht sie, den übergeordneten Prozess unabhängig vom untergeordneten Prozess zu beenden. const { spawn } = erfordern('Kindprozess'); const Unterprozess = spawn(Prozess.argv[0], ['child_program.js'], { losgelöst: wahr, stdio: "ignorieren" }); Unterprozess.unref(); Schauen wir uns abschließend an, wie Nachrichten über ChildProcess gesendet werden: subprocess.send(Nachricht[, sendHandle[, Optionen]][, Rückruf]) Dabei ist „Nachricht“ die zu sendende Nachricht und „Rückruf“ der Rückruf nach dem Senden der Nachricht. sendHandle ist etwas Besonderes. Es kann ein TCP-Server- oder Socket-Objekt sein und diese Handles an den untergeordneten Prozess übergeben. Der untergeordnete Prozess übergibt den Handle im Nachrichtenereignis an die Rückruffunktion, sodass dieser im untergeordneten Prozess verarbeitet werden kann. Schauen wir uns ein Beispiel für die Übergabe an einen TCP-Server an. Sehen wir uns zunächst den Hauptprozess an: const Unterprozess = erfordern ('Unterprozess').fork ('Unterprozess.js'); //Öffne das Serverobjekt und sende den Handle. const server = require('net').createServer(); server.on('Verbindung', (Socket) => { socket.end('Wird vom übergeordneten Prozess verarbeitet'); }); server.listen(1337, () => { Unterprozess.senden('Server', Server); }); Schauen Sie sich den Unterprozess noch einmal an: process.on('Nachricht', (m, Server) => { wenn (m === 'Server') { server.on('Verbindung', (Socket) => { socket.end('Vom untergeordneten Prozess verarbeitet'); }); } }); Sie können sehen, dass der untergeordnete Prozess den Server-Handle empfängt und auf das Verbindungsereignis im untergeordneten Prozess wartet. Sehen wir uns ein Beispiel für die Übergabe eines Socket-Objekts an: onst { fork } = erfordern('untergeordneter_Prozess'); const normal = fork('subprocess.js', ['normal']); const special = fork('Unterprozess.js', ['special']); // Starten Sie den Server und senden Sie den Socket an den untergeordneten Prozess. // Verwenden Sie „pauseOnConnect“, um zu verhindern, dass der Socket gelesen wird, bevor er an den untergeordneten Prozess gesendet wird. const server = require('net').createServer({ pauseOnConnect: true }); server.on('Verbindung', (Socket) => { // Besondere Priorität. wenn (socket.remoteAddress === '74.125.127.100') { speziell.send('Socket', Socket); zurückkehren; } // Normale Priorität. normal.send('socket', socket); }); server.listen(1337); Inhalt von subprocess.js: Prozess.Ein('Nachricht', (m, Socket) => { wenn (m === 'Socket') { wenn (Buchse) { // Überprüfen, ob der Client-Socket vorhanden ist. // Der Socket kann zwischen dem Senden und dem Empfangen durch den Kindprozess geschlossen werden. socket.end(`Anfrage wird mit der Priorität ${process.argv[2]} verarbeitet`); } } }); Der Hauptprozess erstellt zwei Unterprozesse, einen für besondere Priorität und einen für normale Priorität. Einen Prozess asynchron erstellenDas Modul child_process bietet vier Möglichkeiten, Prozesse asynchron zu erstellen, nämlich child_process.spawn(), child_process.fork(), child_process.exec() und child_process.execFile(). Schauen wir uns zunächst die Definition der einzelnen Methoden an: child_process.spawn(Befehl[, Argumente][, Optionen]) child_process.fork(Modulpfad[, Argumente][, Optionen]) child_process.exec(Befehl[, Optionen][, Rückruf]) child_process.execFile(Datei[, Argumente][, Optionen][, Rückruf]) Unter ihnen ist child_process.spawn die Basis, die asynchron einen neuen Prozess generiert. Andere Forks, Execs und ExecFiles werden alle basierend auf Spawn generiert. Fork generiert einen neuen Node.js-Prozess. exec und execFile führen neue Befehle in einem neuen Prozess mit Rückruf aus. Der Unterschied zwischen ihnen besteht darin, dass Sie in der Windows-Umgebung eine .bat- oder .cmd-Datei nicht ohne ein Shell-Terminal ausführen können. Derzeit kann es nur mit exec gestartet werden. execFile ist nicht ausführbar. Alternativ können Sie Spawn verwenden. Sehen wir uns ein Beispiel für die Verwendung von „spawn“ und „exec“ in Windows an: // Nur unter Windows. const { spawn } = erfordern('Kindprozess'); const bat = spawn('cmd.exe', ['/c', 'my.bat']); bat.stdout.on('Daten', (Daten) => { Konsole.log(Daten.toString()); }); bat.stderr.on('Daten', (Daten) => { Konsole.Fehler(Daten.toString()); }); bat.on('Beenden', (Code) => { console.log(`Unterprozess beendet, Exitcode $[code]`); }); const { exec, spawn } = erfordern('Kindprozess'); exec('my.bat', (err, stdout, stderr) => { wenn (Fehler) { Konsole.Fehler(Fehler); zurückkehren; } konsole.log(stdout); }); // Skript mit Leerzeichen im Dateinamen: const bat = spawn('"mein Skript.cmd"', ['a', 'b'], { shell: true }); // oder: exec('"mein Skript.cmd" a b', (err, stdout, stderr) => { // ... }); Synchroner ErstellungsprozessUm einen Prozess synchron zu erstellen, können Sie child_process.spawnSync(), child_process.execSync() und child_process.execFileSync() verwenden. Die synchrone Methode blockiert die Node.js-Ereignisschleife und unterbricht die Ausführung jeglichen anderen Codes, bis der untergeordnete Prozess beendet wird. Für manche Skriptaufgaben ist es üblicher, einen synchronen Erstellungsprozess zu verwenden. Dies ist das Ende dieses Artikels zum Erstellen eines untergeordneten Prozesses in nodejs. Weitere Informationen zum Erstellen eines untergeordneten Prozesses in nodejs finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen! Das könnte Sie auch interessieren:
|
<<: Lösung für das Problem mit verstümmelten chinesischen Schriftzeichen in MySQL unter Ubuntu
>>: Lösung für das Problem, dass Docker Nginx nach dem Ausführen nicht mehr aufgerufen werden kann
Inhaltsverzeichnis 1. Subroutensyntax 2. Beispiel...
Hexadezimalcodetabelle verschiedener Farben [Teil ...
1. Schauen wir uns zunächst eine Anweisung zur Ta...
Inhaltsverzeichnis 1. Standardwerte für Funktions...
Vorwort Dieser Artikel stellt hauptsächlich die r...
Inhaltsverzeichnis 1. Einleitung 2. Grundsatz Pra...
Dieser Artikel stellt hauptsächlich den Prozess d...
brauchen Nachdem der Benutzer das Formular ausgef...
1. Was ist Vue Vue ist ein fortschrittliches Fram...
1. Wie MySQL Indizes verwendet Indizes werden ver...
Wenn die Tabelle breit ist, kann es zu einem Über...
1. Befehlseinführung Der Befehl tac (umgekehrte R...
Verwenden Sie runlike, um die Docker Run-Startpar...
Wir hoffen, dass wir durch die Einbindung der Wet...
Dieser Artikel beschreibt einen Vorschlag für ein...