Worker-Threads
[Stabil: 2 - Stabil]
Stabil: 2 Stabilität: 2 - Stabil
Quellcode: lib/worker_threads.js
Das Modul node:worker_threads
ermöglicht die Verwendung von Threads, die JavaScript parallel ausführen. Um darauf zuzugreifen:
const worker = require('node:worker_threads')
Worker (Threads) sind nützlich, um CPU-intensive JavaScript-Operationen durchzuführen. Bei E/A-intensiven Arbeiten helfen sie nicht viel. Die in Node.js eingebauten asynchronen E/A-Operationen sind effizienter als Worker es sein können.
Im Gegensatz zu child_process
oder cluster
können worker_threads
Speicher gemeinsam nutzen. Sie tun dies, indem sie ArrayBuffer
-Instanzen übertragen oder SharedArrayBuffer
-Instanzen gemeinsam nutzen.
const { Worker, isMainThread, parentPort, workerData } = require('node:worker_threads')
if (isMainThread) {
module.exports = function parseJSAsync(script) {
return new Promise((resolve, reject) => {
const worker = new Worker(__filename, {
workerData: script,
})
worker.on('message', resolve)
worker.on('error', reject)
worker.on('exit', code => {
if (code !== 0) reject(new Error(`Worker wurde mit Exit-Code ${code} gestoppt`))
})
})
}
} else {
const { parse } = require('some-js-parsing-library')
const script = workerData
parentPort.postMessage(parse(script))
}
Das obige Beispiel erzeugt einen Worker-Thread für jeden parseJSAsync()
-Aufruf. In der Praxis sollte für diese Art von Aufgaben ein Pool von Workern verwendet werden. Andernfalls würde der Overhead beim Erstellen von Workern wahrscheinlich ihren Nutzen übersteigen.
Verwenden Sie bei der Implementierung eines Worker-Pools die AsyncResource
-API, um Diagnosetools (z. B. zur Bereitstellung asynchroner Stack-Traces) über die Korrelation zwischen Aufgaben und deren Ergebnissen zu informieren. Ein Beispiel für eine Implementierung finden Sie unter "Verwenden von AsyncResource
für einen Worker
-Threadpool" in der async_hooks
-Dokumentation.
Worker-Threads erben standardmäßig nicht-prozessspezifische Optionen. Informationen zur Anpassung von Worker-Thread-Optionen, insbesondere der argv
- und execArgv
-Optionen, finden Sie unter Worker-Konstruktoroptionen
.
worker.getEnvironmentData(key)
[Verlauf]
Version | Änderungen |
---|---|
v17.5.0, v16.15.0 | Nicht mehr experimentell. |
v15.12.0, v14.18.0 | Hinzugefügt in: v15.12.0, v14.18.0 |
key
<any> Ein beliebiger, klonbarer JavaScript-Wert, der als <Map>-Schlüssel verwendet werden kann.- Gibt zurück: <any>
Innerhalb eines Worker-Threads gibt worker.getEnvironmentData()
einen Klon der Daten zurück, die dem erzeugenden Thread über worker.setEnvironmentData()
übergeben wurden. Jeder neue Worker
erhält automatisch seine eigene Kopie der Umgebungsdaten.
const { Worker, isMainThread, setEnvironmentData, getEnvironmentData } = require('node:worker_threads')
if (isMainThread) {
setEnvironmentData('Hallo', 'Welt!')
const worker = new Worker(__filename)
} else {
console.log(getEnvironmentData('Hallo')) // Gibt 'Welt!' aus.
}
worker.isMainThread
Hinzugefügt in: v10.5.0
Ist true
, wenn dieser Code nicht innerhalb eines Worker
-Threads ausgeführt wird.
const { Worker, isMainThread } = require('node:worker_threads')
if (isMainThread) {
// Lädt die aktuelle Datei in einer Worker-Instanz neu.
new Worker(__filename)
} else {
console.log('Im Worker!')
console.log(isMainThread) // Gibt 'false' aus.
}
worker.markAsUntransferable(object)
Hinzugefügt in: v14.5.0, v12.19.0
object
<any> Ein beliebiger JavaScript-Wert.
Markiert ein Objekt als nicht übertragbar. Wenn object
in der Übertragungsliste eines port.postMessage()
-Aufrufs vorkommt, wird ein Fehler ausgelöst. Dies ist ein No-Op, wenn object
ein primitiver Wert ist.
Dies ist insbesondere sinnvoll für Objekte, die geklont und nicht übertragen werden können und die von anderen Objekten auf der sendenden Seite verwendet werden. Node.js markiert beispielsweise die ArrayBuffer
s, die es für seinen Buffer
-Pool verwendet, damit.
Diese Operation kann nicht rückgängig gemacht werden.
const { MessageChannel, markAsUntransferable } = require('node:worker_threads')
const pooledBuffer = new ArrayBuffer(8)
const typedArray1 = new Uint8Array(pooledBuffer)
const typedArray2 = new Float64Array(pooledBuffer)
markAsUntransferable(pooledBuffer)
const { port1 } = new MessageChannel()
try {
// Dies löst einen Fehler aus, da pooledBuffer nicht übertragbar ist.
port1.postMessage(typedArray1, [typedArray1.buffer])
} catch (error) {
// error.name === 'DataCloneError'
}
// Die folgende Zeile gibt den Inhalt von typedArray1 aus -- er besitzt immer noch
// seinen Speicher und wurde nicht übertragen. Ohne
// `markAsUntransferable()` würde dies ein leeres Uint8Array ausgeben und der
// postMessage-Aufruf wäre erfolgreich gewesen.
// typedArray2 ist ebenfalls intakt.
console.log(typedArray1)
console.log(typedArray2)
Es gibt kein Äquivalent zu dieser API in Browsern.
worker.isMarkedAsUntransferable(object)
Hinzugefügt in: v21.0.0
Prüft, ob ein Objekt mit markAsUntransferable()
als nicht übertragbar markiert wurde.
const { markAsUntransferable, isMarkedAsUntransferable } = require('node:worker_threads')
const pooledBuffer = new ArrayBuffer(8)
markAsUntransferable(pooledBuffer)
isMarkedAsUntransferable(pooledBuffer) // Gibt true zurück.
Es gibt keine Entsprechung zu dieser API in Browsern.
worker.markAsUncloneable(object)
Hinzugefügt in: v23.0.0
object
<any> Beliebiger JavaScript-Wert.
Markiert ein Objekt als nicht klonbar. Wenn object
als message
in einem port.postMessage()
Aufruf verwendet wird, wird ein Fehler ausgelöst. Dies ist ein No-Op, wenn object
ein primitiver Wert ist.
Dies hat keine Auswirkungen auf ArrayBuffer
oder ähnliche Buffer
-Objekte.
Diese Operation kann nicht rückgängig gemacht werden.
const { markAsUncloneable } = require('node:worker_threads')
const anyObject = { foo: 'bar' }
markAsUncloneable(anyObject)
const { port1 } = new MessageChannel()
try {
// Dies wird einen Fehler auslösen, da anyObject nicht klonbar ist.
port1.postMessage(anyObject)
} catch (error) {
// error.name === 'DataCloneError'
}
Es gibt keine Entsprechung zu dieser API in Browsern.
worker.moveMessagePortToContext(port, contextifiedSandbox)
Hinzugefügt in: v11.13.0
port
<MessagePort> Der zu übertragende Nachrichtenport.contextifiedSandbox
<Object> Ein kontextualisiertes Objekt, wie von dervm.createContext()
Methode zurückgegeben.- Gibt zurück: <MessagePort>
Überträgt einen MessagePort
in einen anderen vm
Kontext. Das ursprüngliche port
-Objekt wird unbrauchbar gemacht, und die zurückgegebene MessagePort
-Instanz übernimmt dessen Platz.
Der zurückgegebene MessagePort
ist ein Objekt im Zielkontext und erbt von seiner globalen Object
-Klasse. Objekte, die an den port.onmessage()
Listener übergeben werden, werden ebenfalls im Zielkontext erstellt und erben von seiner globalen Object
-Klasse.
Der erstellte MessagePort
erbt jedoch nicht mehr von EventTarget
, und nur port.onmessage()
kann verwendet werden, um Ereignisse damit zu empfangen.
worker.parentPort
Hinzugefügt in: v10.5.0
Wenn dieser Thread ein Worker
ist, ist dies ein MessagePort
, der die Kommunikation mit dem übergeordneten Thread ermöglicht. Nachrichten, die mit parentPort.postMessage()
gesendet werden, sind im übergeordneten Thread mit worker.on('message')
verfügbar, und Nachrichten, die vom übergeordneten Thread mit worker.postMessage()
gesendet werden, sind in diesem Thread mit parentPort.on('message')
verfügbar.
const { Worker, isMainThread, parentPort } = require('node:worker_threads')
if (isMainThread) {
const worker = new Worker(__filename)
worker.once('message', message => {
console.log(message) // Gibt 'Hello, world!' aus.
})
worker.postMessage('Hello, world!')
} else {
// Wenn eine Nachricht vom übergeordneten Thread empfangen wird, senden Sie sie zurück:
parentPort.once('message', message => {
parentPort.postMessage(message)
})
}
worker.postMessageToThread(threadId, value[, transferList][, timeout])
Hinzugefügt in: v22.5.0
[Stabil: 1 - Experimentell]
Stabil: 1 Stabilität: 1.1 - Aktive Entwicklung
threadId
<number> Die Ziel-Thread-ID. Wenn die Thread-ID ungültig ist, wird einERR_WORKER_MESSAGING_FAILED
-Fehler ausgelöst. Wenn die Ziel-Thread-ID die aktuelle Thread-ID ist, wird einERR_WORKER_MESSAGING_SAME_THREAD
-Fehler ausgelöst.value
<any> Der zu sendende Wert.transferList
<Object[]> Wenn ein oder mehrereMessagePort
-ähnliche Objekte invalue
übergeben werden, ist einetransferList
für diese Elemente erforderlich oderERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST
wird ausgelöst. Sieheport.postMessage()
für weitere Informationen.timeout
<number> Zeit, die in Millisekunden auf die Zustellung der Nachricht gewartet wird. Standardmäßig ist esundefined
, was bedeutet, dass unbegrenzt gewartet wird. Wenn die Operation zeitlich überschritten wird, wird einERR_WORKER_MESSAGING_TIMEOUT
-Fehler ausgelöst.- Gibt zurück: <Promise> Ein Promise, das erfüllt wird, wenn die Nachricht vom Ziel-Thread erfolgreich verarbeitet wurde.
Sendet einen Wert an einen anderen Worker, der durch seine Thread-ID identifiziert wird.
Wenn der Ziel-Thread keinen Listener für das workerMessage
-Ereignis hat, löst die Operation einen ERR_WORKER_MESSAGING_FAILED
-Fehler aus.
Wenn der Ziel-Thread während der Verarbeitung des workerMessage
-Ereignisses einen Fehler ausgelöst hat, löst die Operation einen ERR_WORKER_MESSAGING_ERRORED
-Fehler aus.
Diese Methode sollte verwendet werden, wenn der Ziel-Thread nicht der direkte übergeordnete oder untergeordnete Thread des aktuellen Threads ist. Wenn die beiden Threads über- und untergeordnet sind, verwenden Sie require('node:worker_threads').parentPort.postMessage()
und worker.postMessage()
, um die Threads kommunizieren zu lassen.
Das folgende Beispiel zeigt die Verwendung von postMessageToThread
: Es erstellt 10 verschachtelte Threads, der letzte wird versuchen, mit dem Hauptthread zu kommunizieren.
import { fileURLToPath } from 'node:url'
import process from 'node:process'
import { postMessageToThread, threadId, workerData, Worker } from 'node:worker_threads'
const channel = new BroadcastChannel('sync')
const level = workerData?.level ?? 0
if (level < 10) {
const worker = new Worker(fileURLToPath(import.meta.url), {
workerData: { level: level + 1 },
})
}
if (level === 0) {
process.on('workerMessage', (value, source) => {
console.log(`${source} -> ${threadId}:`, value)
postMessageToThread(source, { message: 'pong' })
})
} else if (level === 10) {
process.on('workerMessage', (value, source) => {
console.log(`${source} -> ${threadId}:`, value)
channel.postMessage('done')
channel.close()
})
await postMessageToThread(0, { message: 'ping' })
}
channel.onmessage = channel.close
const { postMessageToThread, threadId, workerData, Worker } = require('node:worker_threads')
const channel = new BroadcastChannel('sync')
const level = workerData?.level ?? 0
if (level < 10) {
const worker = new Worker(__filename, {
workerData: { level: level + 1 },
})
}
if (level === 0) {
process.on('workerMessage', (value, source) => {
console.log(`${source} -> ${threadId}:`, value)
postMessageToThread(source, { message: 'pong' })
})
} else if (level === 10) {
process.on('workerMessage', (value, source) => {
console.log(`${source} -> ${threadId}:`, value)
channel.postMessage('done')
channel.close()
})
postMessageToThread(0, { message: 'ping' })
}
channel.onmessage = channel.close
worker.receiveMessageOnPort(port)
[Verlauf]
Version | Änderungen |
---|---|
v15.12.0 | Das Port-Argument kann nun auch auf einen BroadcastChannel verweisen. |
v12.3.0 | Hinzugefügt in: v12.3.0 |
port
<MessagePort> | <BroadcastChannel>- Gibt zurück: <Object> | <undefined>
Empfängt eine einzelne Nachricht von einem gegebenen MessagePort
. Wenn keine Nachricht verfügbar ist, wird undefined
zurückgegeben, andernfalls ein Objekt mit einer einzelnen message
-Eigenschaft, die die Nutzlast der Nachricht enthält, entsprechend der ältesten Nachricht in der Warteschlange des MessagePort
.
const { MessageChannel, receiveMessageOnPort } = require('node:worker_threads')
const { port1, port2 } = new MessageChannel()
port1.postMessage({ hello: 'world' })
console.log(receiveMessageOnPort(port2))
// Gibt aus: { message: { hello: 'world' } }
console.log(receiveMessageOnPort(port2))
// Gibt aus: undefined
Wenn diese Funktion verwendet wird, wird kein 'message'
-Ereignis ausgelöst und der onmessage
-Listener wird nicht aufgerufen.
worker.resourceLimits
Hinzugefügt in: v13.2.0, v12.16.0
Stellt den Satz von Ressourcenbeschränkungen der JS-Engine innerhalb dieses Worker-Threads bereit. Wenn die Option resourceLimits
an den Worker
-Konstruktor übergeben wurde, entspricht dies seinen Werten.
Wenn dies im Hauptthread verwendet wird, ist sein Wert ein leeres Objekt.
worker.SHARE_ENV
Hinzugefügt in: v11.14.0
Ein spezieller Wert, der als env
-Option des Worker
-Konstruktors übergeben werden kann, um anzugeben, dass der aktuelle Thread und der Worker-Thread gemeinsam Lese- und Schreibzugriff auf denselben Satz von Umgebungsvariablen haben sollen.
const { Worker, SHARE_ENV } = require('node:worker_threads')
new Worker('process.env.SET_IN_WORKER = "foo"', { eval: true, env: SHARE_ENV }).on('exit', () => {
console.log(process.env.SET_IN_WORKER) // Gibt 'foo' aus.
})
worker.setEnvironmentData(key[, value])
[Verlauf]
Version | Änderungen |
---|---|
v17.5.0, v16.15.0 | Nicht mehr experimentell. |
v15.12.0, v14.18.0 | Hinzugefügt in: v15.12.0, v14.18.0 |
key
<any> Ein beliebiger, klonbarer JavaScript-Wert, der als <Map>-Schlüssel verwendet werden kann.value
<any> Ein beliebiger, klonbarer JavaScript-Wert, der geklont und automatisch an alle neuenWorker
-Instanzen übergeben wird. Wennvalue
alsundefined
übergeben wird, wird jeder zuvor für denkey
gesetzte Wert gelöscht.
Die worker.setEnvironmentData()
-API setzt den Inhalt von worker.getEnvironmentData()
im aktuellen Thread und allen neuen Worker
-Instanzen, die aus dem aktuellen Kontext erzeugt werden.
worker.threadId
Hinzugefügt in: v10.5.0
Eine ganzzahlige Kennung für den aktuellen Thread. Auf dem entsprechenden Worker-Objekt (falls vorhanden) ist sie als worker.threadId
verfügbar. Dieser Wert ist für jede Worker
-Instanz innerhalb eines einzigen Prozesses eindeutig.
worker.workerData
Hinzugefügt in: v10.5.0
Ein beliebiger JavaScript-Wert, der eine Kopie der Daten enthält, die dem Konstruktor Worker
dieses Threads übergeben wurden.
Die Daten werden so geklont, als ob sie mit postMessage()
gemäß dem HTML-Struktur-Klon-Algorithmus geklont würden.
const { Worker, isMainThread, workerData } = require('node:worker_threads')
if (isMainThread) {
const worker = new Worker(__filename, { workerData: 'Hallo, Welt!' })
} else {
console.log(workerData) // Gibt 'Hallo, Welt!' aus.
}
Klasse: BroadcastChannel extends EventTarget
[Verlauf]
Version | Änderungen |
---|---|
v18.0.0 | Nicht mehr experimentell. |
v15.4.0 | Hinzugefügt in: v15.4.0 |
Instanzen von BroadcastChannel
ermöglichen eine asynchrone Eins-zu-Viele-Kommunikation mit allen anderen BroadcastChannel
-Instanzen, die an denselben Kanalnamen gebunden sind.
'use strict'
const { isMainThread, BroadcastChannel, Worker } = require('node:worker_threads')
const bc = new BroadcastChannel('hello')
if (isMainThread) {
let c = 0
bc.onmessage = event => {
console.log(event.data)
if (++c === 10) bc.close()
}
for (let n = 0; n < 10; n++) new Worker(__filename)
} else {
bc.postMessage('Hallo von jedem Worker')
bc.close()
}
new BroadcastChannel(name)
Hinzugefügt in: v15.4.0
name
<beliebig> Der Name des Kanals, mit dem eine Verbindung hergestellt werden soll. Jeder JavaScript-Wert, der mit${name}
in einen String konvertiert werden kann, ist zulässig.
broadcastChannel.close()
Hinzugefügt in: v15.4.0
Schließt die BroadcastChannel
-Verbindung.
broadcastChannel.onmessage
Hinzugefügt in: v15.4.0
- Typ: <Funktion> Wird mit einem einzelnen
MessageEvent
-Argument aufgerufen, wenn eine Nachricht empfangen wird.
broadcastChannel.onmessageerror
Hinzugefügt in: v15.4.0
- Typ: <Funktion> Wird aufgerufen, wenn eine empfangene Nachricht nicht deserialisiert werden kann.
broadcastChannel.postMessage(message)
Hinzugefügt in: v15.4.0
message
<any> Jeder klonbare JavaScript-Wert.
broadcastChannel.ref()
Hinzugefügt in: v15.4.0
Das Gegenteil von unref()
. Das Aufrufen von ref()
auf einem zuvor unref()
ed BroadcastChannel bewirkt nicht, dass das Programm beendet wird, wenn es der einzige aktive Handle ist (das Standardverhalten). Wenn der Port ref()
ed ist, hat ein erneutes Aufrufen von ref()
keine Auswirkung.
broadcastChannel.unref()
Hinzugefügt in: v15.4.0
Das Aufrufen von unref()
auf einem BroadcastChannel ermöglicht es dem Thread, sich zu beenden, wenn dies der einzige aktive Handle im Ereignissystem ist. Wenn der BroadcastChannel bereits unref()
ed ist, hat ein erneutes Aufrufen von unref()
keine Auswirkung.
Klasse: MessageChannel
Hinzugefügt in: v10.5.0
Instanzen der worker.MessageChannel
-Klasse stellen einen asynchronen Zwei-Wege-Kommunikationskanal dar. Die MessageChannel
hat keine eigenen Methoden. new MessageChannel()
erzeugt ein Objekt mit den Eigenschaften port1
und port2
, die auf verknüpfte MessagePort
-Instanzen verweisen.
const { MessageChannel } = require('node:worker_threads')
const { port1, port2 } = new MessageChannel()
port1.on('message', message => console.log('empfangen', message))
port2.postMessage({ foo: 'bar' })
// Gibt aus: empfangen { foo: 'bar' } vom `port1.on('message')`-Listener
Klasse: MessagePort
[Verlauf]
Version | Änderungen |
---|---|
v14.7.0 | Diese Klasse erbt jetzt von EventTarget anstelle von EventEmitter . |
v10.5.0 | Hinzugefügt in: v10.5.0 |
- Erweitert: <EventTarget>
Instanzen der worker.MessagePort
-Klasse stellen ein Ende eines asynchronen Zwei-Wege-Kommunikationskanals dar. Es kann verwendet werden, um strukturierte Daten, Speicherbereiche und andere MessagePort
s zwischen verschiedenen Worker
s zu übertragen.
Diese Implementierung entspricht Browser MessagePort
s.
Ereignis: 'close'
Hinzugefügt in: v10.5.0
Das Ereignis 'close'
wird einmal ausgelöst, wenn eine Seite des Kanals getrennt wurde.
const { MessageChannel } = require('node:worker_threads')
const { port1, port2 } = new MessageChannel()
// Gibt Folgendes aus:
// foobar
// geschlossen!
port2.on('message', message => console.log(message))
port2.on('close', () => console.log('geschlossen!'))
port1.postMessage('foobar')
port1.close()
Ereignis: 'message'
Hinzugefügt in: v10.5.0
value
<any> Der übertragene Wert
Das Ereignis 'message'
wird für jede eingehende Nachricht ausgelöst und enthält den geklonten Eingabewert von port.postMessage()
.
Listener für dieses Ereignis empfangen einen Klon des value
-Parameters, wie er an postMessage()
übergeben wurde, und keine weiteren Argumente.
Ereignis: 'messageerror'
Hinzugefügt in: v14.5.0, v12.19.0
error
<Error> Ein Fehlerobjekt
Das Ereignis 'messageerror'
wird ausgelöst, wenn die Deserialisierung einer Nachricht fehlgeschlagen ist.
Derzeit wird dieses Ereignis ausgelöst, wenn beim Instanziieren des übermittelten JS-Objekts auf der Empfängerseite ein Fehler auftritt. Solche Situationen sind selten, können aber beispielsweise auftreten, wenn bestimmte Node.js-API-Objekte in einem vm.Context
empfangen werden (wo Node.js-APIs derzeit nicht verfügbar sind).
port.close()
Hinzugefügt in: v10.5.0
Deaktiviert das weitere Senden von Nachrichten auf beiden Seiten der Verbindung. Diese Methode kann aufgerufen werden, wenn über diesen MessagePort
keine weitere Kommunikation stattfindet.
Das 'close'
-Ereignis wird auf beiden MessagePort
-Instanzen ausgelöst, die Teil des Kanals sind.
port.postMessage(value[, transferList])
[Verlauf]
Version | Änderungen |
---|---|
v21.0.0 | Es wird ein Fehler ausgelöst, wenn sich ein nicht übertragbares Objekt in der Übertragungsliste befindet. |
v15.6.0 | X509Certificate wurde der Liste der klonbaren Typen hinzugefügt. |
v15.0.0 | CryptoKey wurde der Liste der klonbaren Typen hinzugefügt. |
v15.14.0, v14.18.0 | 'BlockList' zur Liste der klonbaren Typen hinzugefügt. |
v15.9.0, v14.18.0 | 'Histogram'-Typen zur Liste der klonbaren Typen hinzugefügt. |
v14.5.0, v12.19.0 | KeyObject wurde der Liste der klonbaren Typen hinzugefügt. |
v14.5.0, v12.19.0 | FileHandle wurde der Liste der übertragbaren Typen hinzugefügt. |
v10.5.0 | Hinzugefügt in: v10.5.0 |
value
<any>transferList
<Object[]>
Sendet einen JavaScript-Wert an die Empfängerseite dieses Kanals. value
wird auf eine Weise übertragen, die mit dem HTML-Algorithmus für strukturiertes Klonen kompatibel ist.
Insbesondere die wesentlichen Unterschiede zu JSON
sind:
value
kann zirkuläre Referenzen enthalten.value
kann Instanzen von integrierten JS-Typen wieRegExp
s,BigInt
s,Map
s,Set
s usw. enthalten.value
kann typisierte Arrays enthalten, sowohl unter Verwendung vonArrayBuffer
s als auch vonSharedArrayBuffer
s.value
kannWebAssembly.Module
-Instanzen enthalten.value
darf keine nativen (C++-gestützten) Objekte enthalten, außer:
const { MessageChannel } = require('node:worker_threads')
const { port1, port2 } = new MessageChannel()
port1.on('message', message => console.log(message))
const circularData = {}
circularData.foo = circularData
// Gibt aus: { foo: [Circular] }
port2.postMessage(circularData)
transferList
kann eine Liste von ArrayBuffer
-, MessagePort
- und FileHandle
-Objekten sein. Nach der Übertragung sind sie auf der sendenden Seite des Kanals nicht mehr verwendbar (auch wenn sie nicht in value
enthalten sind). Anders als bei Child-Prozessen wird die Übertragung von Handles wie Netzwerk-Sockets derzeit nicht unterstützt.
Wenn value
SharedArrayBuffer
-Instanzen enthält, sind diese von beiden Threads aus zugänglich. Sie können nicht in transferList
aufgeführt werden.
value
kann weiterhin ArrayBuffer
-Instanzen enthalten, die nicht in transferList
enthalten sind; in diesem Fall wird der zugrunde liegende Speicher kopiert und nicht verschoben.
const { MessageChannel } = require('node:worker_threads')
const { port1, port2 } = new MessageChannel()
port1.on('message', message => console.log(message))
const uint8Array = new Uint8Array([1, 2, 3, 4])
// Dies sendet eine Kopie von `uint8Array`:
port2.postMessage(uint8Array)
// Dies kopiert keine Daten, sondern macht `uint8Array` unbrauchbar:
port2.postMessage(uint8Array, [uint8Array.buffer])
// Der Speicher für `sharedUint8Array` ist sowohl vom
// Original als auch von der von `.on('message')` empfangenen Kopie
// zugänglich:
const sharedUint8Array = new Uint8Array(new SharedArrayBuffer(4))
port2.postMessage(sharedUint8Array)
// Dies überträgt einen neu erstellten Nachrichtenport an den Empfänger.
// Dies kann beispielsweise verwendet werden, um Kommunikationskanäle zwischen
// mehreren `Worker`-Threads zu erstellen, die Kinder desselben Eltern-Threads sind.
const otherChannel = new MessageChannel()
port2.postMessage({ port: otherChannel.port1 }, [otherChannel.port1])
Das Nachrichtobjekt wird sofort geklont und kann nach dem Senden ohne Seiteneffekte geändert werden.
Weitere Informationen zu den Serialisierungs- und Deserialisierungsmechanismen hinter dieser API finden Sie in der Serialisierungs-API des Moduls node:v8
.
Überlegungen beim Übertragen von TypedArrays und Buffers
Alle TypedArray
- und Buffer
-Instanzen sind Ansichten über einen zugrunde liegenden ArrayBuffer
. Das heißt, es ist der ArrayBuffer
, der die Rohdaten tatsächlich speichert, während die TypedArray
- und Buffer
-Objekte eine Möglichkeit bieten, die Daten anzuzeigen und zu manipulieren. Es ist möglich und üblich, dass mehrere Ansichten über derselben ArrayBuffer
-Instanz erstellt werden. Bei der Verwendung einer Übertragungsliste zum Übertragen eines ArrayBuffer
ist große Vorsicht geboten, da dies dazu führt, dass alle TypedArray
- und Buffer
-Instanzen, die denselben ArrayBuffer
verwenden, unbrauchbar werden.
const ab = new ArrayBuffer(10)
const u1 = new Uint8Array(ab)
const u2 = new Uint16Array(ab)
console.log(u2.length) // gibt 5 aus
port.postMessage(u1, [u1.buffer])
console.log(u2.length) // gibt 0 aus
Bei Buffer
-Instanzen hängt insbesondere davon, wie die Instanzen erstellt wurden, ob der zugrunde liegende ArrayBuffer
übertragen oder geklont werden kann, was oft nicht zuverlässig bestimmt werden kann.
Ein ArrayBuffer
kann mit markAsUntransferable()
gekennzeichnet werden, um anzugeben, dass er immer geklont und niemals übertragen werden soll.
Je nachdem, wie eine Buffer
-Instanz erstellt wurde, besitzt sie möglicherweise ihren zugrunde liegenden ArrayBuffer
oder auch nicht. Ein ArrayBuffer
darf nur dann übertragen werden, wenn bekannt ist, dass die Buffer
-Instanz ihn besitzt. Insbesondere bei Buffer
s, die aus dem internen Buffer
-Pool erstellt wurden (z. B. mit Buffer.from()
oder Buffer.allocUnsafe()
), ist eine Übertragung nicht möglich und sie werden immer geklont, wodurch eine Kopie des gesamten Buffer
-Pools gesendet wird. Dieses Verhalten kann mit unbeabsichtigter höherer Speichernutzung und möglichen Sicherheitsbedenken einhergehen.
Weitere Informationen zur Buffer
-Poolbildung finden Sie unter Buffer.allocUnsafe()
.
Die ArrayBuffer
s für Buffer
-Instanzen, die mit Buffer.alloc()
oder Buffer.allocUnsafeSlow()
erstellt wurden, können immer übertragen werden, aber dies führt dazu, dass alle anderen vorhandenen Ansichten dieser ArrayBuffer
s unbrauchbar werden.
Überlegungen beim Klonen von Objekten mit Prototypen, Klassen und Accessoren
Da das Klonen von Objekten den HTML-Strukturklon-Algorithmus verwendet, werden nicht aufzählbare Eigenschaften, Eigenschafts-Accessoren und Objektprototypen nicht beibehalten. Insbesondere werden Buffer
-Objekte auf der Empfängerseite als einfache Uint8Array
s gelesen, und Instanzen von JavaScript-Klassen werden als einfache JavaScript-Objekte geklont.
const b = Symbol('b')
class Foo {
#a = 1
constructor() {
this[b] = 2
this.c = 3
}
get d() {
return 4
}
}
const { port1, port2 } = new MessageChannel()
port1.onmessage = ({ data }) => console.log(data)
port2.postMessage(new Foo())
// Gibt aus: { c: 3 }
Diese Einschränkung gilt auch für viele eingebaute Objekte, wie z. B. das globale URL
-Objekt:
const { port1, port2 } = new MessageChannel()
port1.onmessage = ({ data }) => console.log(data)
port2.postMessage(new URL('https://example.org'))
// Gibt aus: { }
port.hasRef()
Hinzugefügt in: v18.1.0, v16.17.0
[Stabil: 1 - Experimentell]
Stabil: 1 Stabilität: 1 - Experimentell
- Gibt zurück: <boolean>
Wenn true, hält das MessagePort
-Objekt die Node.js-Ereignisschleife aktiv.
port.ref()
Hinzugefügt in: v10.5.0
Gegenteil von unref()
. Das Aufrufen von ref()
auf einem zuvor unref()
ed-Port verhindert nicht, dass das Programm beendet wird, wenn es der einzige aktive Handle ist, der noch übrig ist (das Standardverhalten). Wenn der Port ref()
ed ist, hat ein erneuter Aufruf von ref()
keine Auswirkung.
Wenn Listener mit .on('message')
angehängt oder entfernt werden, wird der Port automatisch ref()
ed und unref()
ed, je nachdem, ob Listener für das Ereignis existieren.
port.start()
Hinzugefügt in: v10.5.0
Startet den Empfang von Nachrichten an diesem MessagePort
. Wenn dieser Port als Event-Emitter verwendet wird, wird dies automatisch aufgerufen, sobald 'message'
-Listener angehängt werden.
Diese Methode existiert zur Parität mit der Web MessagePort
API. In Node.js ist sie nur nützlich, um Nachrichten zu ignorieren, wenn kein Event-Listener vorhanden ist. Node.js weicht auch in der Behandlung von .onmessage
ab. Das Setzen ruft automatisch .start()
auf, aber das Aufheben der Einstellung lässt Nachrichten in der Warteschlange, bis ein neuer Handler gesetzt wird oder der Port verworfen wird.
port.unref()
Hinzugefügt in: v10.5.0
Das Aufrufen von unref()
auf einem Port ermöglicht es dem Thread, zu beenden, wenn dies das einzige aktive Handle im Event-System ist. Wenn der Port bereits unref()
ed ist, hat das erneute Aufrufen von unref()
keine Auswirkung.
Wenn Listener mit .on('message')
angehängt oder entfernt werden, wird der Port automatisch ref()
ed und unref()
ed, je nachdem, ob Listener für das Event existieren.
Klasse: Worker
Hinzugefügt in: v10.5.0
- Erweitert: <EventEmitter>
Die Klasse Worker
repräsentiert einen unabhängigen JavaScript-Ausführungsthread. Die meisten Node.js APIs sind innerhalb dessen verfügbar.
Bemerkenswerte Unterschiede innerhalb einer Worker-Umgebung sind:
- Die Streams
process.stdin
,process.stdout
undprocess.stderr
können vom übergeordneten Thread umgeleitet werden. - Die Eigenschaft
require('node:worker_threads').isMainThread
ist auffalse
gesetzt. - Der Nachrichtenport
require('node:worker_threads').parentPort
ist verfügbar. process.exit()
stoppt nicht das gesamte Programm, sondern nur den einzelnen Thread, undprocess.abort()
ist nicht verfügbar.process.chdir()
undprocess
-Methoden, die Gruppen- oder Benutzer-IDs setzen, sind nicht verfügbar.process.env
ist eine Kopie der Umgebungsvariablen des übergeordneten Threads, sofern nicht anders angegeben. Änderungen an einer Kopie sind in anderen Threads nicht sichtbar und für native Add-ons nicht sichtbar (es sei denn,worker.SHARE_ENV
wird alsenv
-Option an denWorker
-Konstruktor übergeben). Unter Windows, im Gegensatz zum Hauptthread, arbeitet eine Kopie der Umgebungsvariablen in einer Fall-sensitiven Weise.process.title
kann nicht geändert werden.- Signale werden nicht über
process.on('...')
geliefert. - Die Ausführung kann jederzeit als Ergebnis des Aufrufs von
worker.terminate()
stoppen. - IPC-Kanäle von übergeordneten Prozessen sind nicht zugänglich.
- Das Modul
trace_events
wird nicht unterstützt. - Native Add-ons können nur von mehreren Threads geladen werden, wenn sie bestimmte Bedingungen erfüllen.
Das Erstellen von Worker
-Instanzen innerhalb anderer Worker
ist möglich.
Wie Web Worker und das node:cluster
-Modul kann eine Zwei-Wege-Kommunikation durch die Übergabe von Nachrichten zwischen den Threads erreicht werden. Intern hat ein Worker
ein eingebautes Paar von MessagePort
s, die bereits miteinander verbunden sind, wenn der Worker
erstellt wird. Während das MessagePort
-Objekt auf der Elterseite nicht direkt exponiert wird, werden seine Funktionalitäten über worker.postMessage()
und das worker.on('message')
Event auf dem Worker
-Objekt für den übergeordneten Thread exponiert.
Um benutzerdefinierte Nachrichtenkanäle zu erstellen (was gegenüber der Verwendung des globalen Standardkanals bevorzugt wird, da es die Trennung von Belangen erleichtert), können Benutzer ein MessageChannel
-Objekt auf jedem Thread erstellen und einen der MessagePort
s auf diesem MessageChannel
über einen bereits vorhandenen Kanal, z. B. den globalen Kanal, an den anderen Thread übergeben.
Weitere Informationen darüber, wie Nachrichten übergeben werden und welche Art von JavaScript-Werten erfolgreich durch die Thread-Barriere transportiert werden können, finden Sie unter port.postMessage()
.
const assert = require('node:assert')
const { Worker, MessageChannel, MessagePort, isMainThread, parentPort } = require('node:worker_threads')
if (isMainThread) {
const worker = new Worker(__filename)
const subChannel = new MessageChannel()
worker.postMessage({ hereIsYourPort: subChannel.port1 }, [subChannel.port1])
subChannel.port2.on('message', value => {
console.log('received:', value)
})
} else {
parentPort.once('message', value => {
assert(value.hereIsYourPort instanceof MessagePort)
value.hereIsYourPort.postMessage('the worker is sending this')
value.hereIsYourPort.close()
})
}
new Worker(filename[, options])
[Verlauf]
Version | Änderungen |
---|---|
v19.8.0, v18.16.0 | Unterstützung für eine name -Option hinzugefügt, die es ermöglicht, dem Worker-Titel einen Namen für das Debugging hinzuzufügen. |
v14.9.0 | Der Parameter filename kann ein WHATWG URL -Objekt mit dem data: -Protokoll sein. |
v14.9.0 | Die Option trackUnmanagedFds wurde standardmäßig auf true gesetzt. |
v14.6.0, v12.19.0 | Die Option trackUnmanagedFds wurde eingeführt. |
v13.13.0, v12.17.0 | Die Option transferList wurde eingeführt. |
v13.12.0, v12.17.0 | Der Parameter filename kann ein WHATWG URL -Objekt mit dem file: -Protokoll sein. |
v13.4.0, v12.16.0 | Die Option argv wurde eingeführt. |
v13.2.0, v12.16.0 | Die Option resourceLimits wurde eingeführt. |
v10.5.0 | Hinzugefügt in: v10.5.0 |
filename
<string> | <URL> Der Pfad zum Hauptskript oder Modul des Workers. Muss entweder ein absoluter Pfad oder ein relativer Pfad sein (d. h. relativ zum aktuellen Arbeitsverzeichnis), der mit./
oder../
beginnt, oder ein WHATWGURL
-Objekt mit demfile:
- oderdata:
-Protokoll. Bei Verwendung einerdata:
URL werden die Daten basierend auf dem MIME-Typ unter Verwendung des ECMAScript-Modulloaders interpretiert. Wennoptions.eval
true
ist, handelt es sich um eine Zeichenfolge, die JavaScript-Code enthält, anstatt um einen Pfad.options
<Object>argv
<any[]> Liste von Argumenten, die in Zeichenketten umgewandelt und anprocess.argv
im Worker angehängt werden. Dies ähnelt im WesentlichenworkerData
, aber die Werte sind im globalenprocess.argv
verfügbar, als wären sie als CLI-Optionen an das Skript übergeben worden.env
<Object> Wenn gesetzt, gibt den Anfangswert vonprocess.env
innerhalb des Worker-Threads an. Als Sonderwert kannworker.SHARE_ENV
verwendet werden, um anzugeben, dass der übergeordnete Thread und der untergeordnete Thread ihre Umgebungsvariablen gemeinsam nutzen sollen; in diesem Fall wirken sich Änderungen amprocess.env
-Objekt des einen Threads auch auf den anderen Thread aus. Standard:process.env
.eval
<boolean> Wenntrue
und das erste Argument einestring
ist, wird das erste Argument des Konstruktors als Skript interpretiert, das ausgeführt wird, sobald der Worker online ist.execArgv
<string[]> Liste der Node-CLI-Optionen, die an den Worker übergeben werden. V8-Optionen (wie--max-old-space-size
) und Optionen, die den Prozess beeinflussen (wie--title
), werden nicht unterstützt. Wenn gesetzt, wird dies alsprocess.execArgv
innerhalb des Workers bereitgestellt. Standardmäßig werden Optionen vom übergeordneten Thread geerbt.stdin
<boolean> Wenn dies auftrue
gesetzt ist, dann stelltworker.stdin
einen beschreibbaren Stream bereit, dessen Inhalt alsprocess.stdin
innerhalb des Workers erscheint. Standardmäßig werden keine Daten bereitgestellt.stdout
<boolean> Wenn dies auftrue
gesetzt ist, dann wirdworker.stdout
nicht automatisch anprocess.stdout
im übergeordneten Element weitergeleitet.stderr
<boolean> Wenn dies auftrue
gesetzt ist, dann wirdworker.stderr
nicht automatisch anprocess.stderr
im übergeordneten Element weitergeleitet.workerData
<any> Jeder JavaScript-Wert, der geklont und alsrequire('node:worker_threads').workerData
verfügbar gemacht wird. Das Klonen erfolgt wie im HTML-Algorithmus für strukturiertes Klonen beschrieben, und es wird ein Fehler ausgelöst, wenn das Objekt nicht geklont werden kann (z. B. weil esfunction
s enthält).trackUnmanagedFds
<boolean> Wenn dies auftrue
gesetzt ist, verfolgt der Worker rohe Dateideskriptoren, die durchfs.open()
undfs.close()
verwaltet werden, und schließt sie, wenn der Worker beendet wird, ähnlich wie andere Ressourcen wie Netzwerk-Sockets oder Dateideskriptoren, die durch dieFileHandle
-API verwaltet werden. Diese Option wird automatisch von allen verschachteltenWorker
s geerbt. Standard:true
.transferList
<Object[]> Wenn ein oder mehrereMessagePort
-ähnliche Objekte inworkerData
übergeben werden, ist einetransferList
für diese Elemente erforderlich, andernfalls wirdERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST
ausgelöst. Sieheport.postMessage()
für weitere Informationen.resourceLimits
<Object> Ein optionales Set von Ressourcenbeschränkungen für die neue JS-Engine-Instanz. Das Erreichen dieser Grenzwerte führt zur Beendigung derWorker
-Instanz. Diese Grenzwerte wirken sich nur auf die JS-Engine aus und nicht auf externe Daten, einschließlich keineArrayBuffer
s. Selbst wenn diese Grenzwerte gesetzt sind, kann der Prozess immer noch abgebrochen werden, wenn eine globale Situation mit unzureichendem Speicher auftritt.maxOldGenerationSizeMb
<number> Die maximale Größe des Haupt-Heaps in MB. Wenn das Befehlszeilenargument--max-old-space-size
gesetzt ist, überschreibt es diese Einstellung.maxYoungGenerationSizeMb
<number> Die maximale Größe eines Heap-Bereichs für kürzlich erstellte Objekte. Wenn das Befehlszeilenargument--max-semi-space-size
gesetzt ist, überschreibt es diese Einstellung.codeRangeSizeMb
<number> Die Größe eines vorab zugewiesenen Speicherbereichs, der für generierten Code verwendet wird.stackSizeMb
<number> Die standardmäßige maximale Stackgröße für den Thread. Kleine Werte können zu unbrauchbaren Worker-Instanzen führen. Standard:4
.name
<string> Ein optionalername
, der dem Worker-Titel für Debugging-/Identifizierungszwecke angehängt wird, wodurch der endgültige Titel als[worker ${id}] ${name}
lautet. Standard:''
.
Ereignis: 'error'
Hinzugefügt in: v10.5.0
err
<Error>
Das Ereignis 'error'
wird ausgelöst, wenn der Worker-Thread eine nicht abgefangene Ausnahme wirft. In diesem Fall wird der Worker beendet.
Ereignis: 'exit'
Hinzugefügt in: v10.5.0
exitCode
<integer>
Das Ereignis 'exit'
wird ausgelöst, sobald der Worker angehalten wurde. Wenn der Worker durch Aufruf von process.exit()
beendet wurde, ist der Parameter exitCode
der übergebene Exit-Code. Wenn der Worker beendet wurde, ist der Parameter exitCode
1
.
Dies ist das letzte Ereignis, das von einer Worker
-Instanz ausgelöst wird.
Ereignis: 'message'
Hinzugefügt in: v10.5.0
value
<any> Der übertragene Wert
Das Ereignis 'message'
wird ausgelöst, wenn der Worker-Thread require('node:worker_threads').parentPort.postMessage()
aufgerufen hat. Weitere Details finden Sie im Ereignis port.on('message')
.
Alle vom Worker-Thread gesendeten Nachrichten werden ausgelöst, bevor das Ereignis 'exit'
auf dem Worker
-Objekt ausgelöst wird.
Ereignis: 'messageerror'
Hinzugefügt in: v14.5.0, v12.19.0
error
<Error> Ein Fehlerobjekt
Das Ereignis 'messageerror'
wird ausgelöst, wenn die Deserialisierung einer Nachricht fehlgeschlagen ist.
Ereignis: 'online'
Hinzugefügt in: v10.5.0
Das Ereignis 'online'
wird ausgelöst, wenn der Worker-Thread mit der Ausführung von JavaScript-Code begonnen hat.
worker.getHeapSnapshot([options])
[Verlauf]
Version | Änderungen |
---|---|
v19.1.0 | Unterstützung für Optionen zum Konfigurieren des Heap-Snapshots. |
v13.9.0, v12.17.0 | Hinzugefügt in: v13.9.0, v12.17.0 |
options
<Object>Gibt zurück: <Promise> Eine Promise für einen lesbaren Stream, der einen V8-Heap-Snapshot enthält
Gibt einen lesbaren Stream für einen V8-Snapshot des aktuellen Zustands des Workers zurück. Weitere Informationen finden Sie unter v8.getHeapSnapshot()
.
Wenn der Worker-Thread nicht mehr ausgeführt wird, was vor dem Auslösen des Ereignisses 'exit'
eintreten kann, wird die zurückgegebene Promise
sofort mit einem Fehler ERR_WORKER_NOT_RUNNING
abgelehnt.
worker.performance
Hinzugefügt in: v15.1.0, v14.17.0, v12.22.0
Ein Objekt, das verwendet werden kann, um Leistungsinformationen von einer Worker-Instanz abzufragen. Ähnlich wie perf_hooks.performance
.
performance.eventLoopUtilization([utilization1[, utilization2]])
Hinzugefügt in: v15.1.0, v14.17.0, v12.22.0
utilization1
<Object> Das Ergebnis eines vorherigen Aufrufs voneventLoopUtilization()
.utilization2
<Object> Das Ergebnis eines vorherigen Aufrufs voneventLoopUtilization()
vorutilization1
.- Gibt zurück: <Object>
Der gleiche Aufruf wie perf_hooks
eventLoopUtilization()
, außer dass die Werte der Worker-Instanz zurückgegeben werden.
Ein Unterschied besteht darin, dass das Bootstrapping innerhalb eines Workers im Gegensatz zum Hauptthread innerhalb der Event-Schleife erfolgt. Die Event-Schleifen-Auslastung ist also sofort verfügbar, sobald das Skript des Workers mit der Ausführung beginnt.
Eine idle
-Zeit, die nicht ansteigt, deutet nicht darauf hin, dass der Worker im Bootstrap hängen geblieben ist. Die folgenden Beispiele zeigen, wie die gesamte Lebensdauer des Workers nie idle
-Zeit ansammelt, aber dennoch in der Lage ist, Nachrichten zu verarbeiten.
const { Worker, isMainThread, parentPort } = require('node:worker_threads')
if (isMainThread) {
const worker = new Worker(__filename)
setInterval(() => {
worker.postMessage('hi')
console.log(worker.performance.eventLoopUtilization())
}, 100).unref()
return
}
parentPort.on('message', () => console.log('msg')).unref()
;(function r(n) {
if (--n < 0) return
const t = Date.now()
while (Date.now() - t < 300);
setImmediate(r, n)
})(10)
Die Event-Schleifen-Auslastung eines Workers ist erst verfügbar, nachdem das Ereignis 'online'
ausgelöst wurde, und wenn sie davor oder nach dem Ereignis 'exit'
aufgerufen wird, haben alle Eigenschaften den Wert 0
.
worker.postMessage(value[, transferList])
Hinzugefügt in: v10.5.0
value
<beliebig>transferList
<Objekt[]>
Sendet eine Nachricht an den Worker, die über require('node:worker_threads').parentPort.on('message')
empfangen wird. Siehe port.postMessage()
für weitere Details.
worker.ref()
Hinzugefügt in: v10.5.0
Das Gegenteil von unref()
. Der Aufruf von ref()
auf einem zuvor unref()
-ten Worker führt nicht dazu, dass das Programm beendet wird, wenn dies der einzig aktive Handle ist (das Standardverhalten). Wenn der Worker ref()
-iert ist, hat ein erneuter Aufruf von ref()
keine Auswirkung.
worker.resourceLimits
Hinzugefügt in: v13.2.0, v12.16.0
Stellt die Menge an Ressourcenbeschränkungen der JS-Engine für diesen Worker-Thread bereit. Wenn die Option resourceLimits
an den Worker
-Konstruktor übergeben wurde, entspricht dies seinen Werten.
Wenn der Worker angehalten wurde, ist der Rückgabewert ein leeres Objekt.
worker.stderr
Hinzugefügt in: v10.5.0
Dies ist ein lesbarer Stream, der Daten enthält, die in process.stderr
innerhalb des Worker-Threads geschrieben wurden. Wenn stderr: true
nicht an den Worker
-Konstruktor übergeben wurde, werden die Daten an den process.stderr
-Stream des übergeordneten Threads weitergeleitet.
worker.stdin
Hinzugefügt in: v10.5.0
Wenn stdin: true
an den Worker
-Konstruktor übergeben wurde, ist dies ein beschreibbarer Stream. Die in diesen Stream geschriebenen Daten werden im Worker-Thread als process.stdin
zur Verfügung gestellt.
worker.stdout
Hinzugefügt in: v10.5.0
Dies ist ein lesbarer Stream, der Daten enthält, die in process.stdout
innerhalb des Worker-Threads geschrieben wurden. Wenn stdout: true
nicht an den Worker
-Konstruktor übergeben wurde, werden die Daten in den process.stdout
-Stream des übergeordneten Threads geleitet.
worker.terminate()
[Verlauf]
Version | Änderungen |
---|---|
v12.5.0 | Diese Funktion gibt nun eine Promise zurück. Das Übergeben eines Callbacks ist veraltet und war bis zu dieser Version nutzlos, da der Worker tatsächlich synchron beendet wurde. Die Beendigung ist nun eine vollständig asynchrone Operation. |
v10.5.0 | Hinzugefügt in: v10.5.0 |
- Gibt zurück: <Promise>
Stoppt die gesamte JavaScript-Ausführung im Worker-Thread so schnell wie möglich. Gibt eine Promise für den Exit-Code zurück, die erfüllt wird, wenn das Ereignis 'exit'
event ausgelöst wird.
worker.threadId
Hinzugefügt in: v10.5.0
Eine Ganzzahlkennung für den referenzierten Thread. Innerhalb des Worker-Threads ist sie als require('node:worker_threads').threadId
verfügbar. Dieser Wert ist für jede Worker
-Instanz innerhalb eines einzelnen Prozesses eindeutig.
worker.unref()
Hinzugefügt in: v10.5.0
Das Aufrufen von unref()
auf einem Worker ermöglicht es dem Thread, sich zu beenden, wenn dies das einzige aktive Handle im Ereignissystem ist. Wenn der Worker bereits unref()
ed ist, hat ein erneuter Aufruf von unref()
keine Auswirkungen.
Hinweise
Synchrone Blockierung von stdio
Worker
verwenden Message Passing über <MessagePort>, um Interaktionen mit stdio
zu implementieren. Dies bedeutet, dass stdio
-Ausgaben, die von einem Worker
stammen, durch synchronen Code am empfangenden Ende blockiert werden können, der die Node.js-Ereignisschleife blockiert.
import { Worker, isMainThread } from 'node:worker_threads'
if (isMainThread) {
new Worker(new URL(import.meta.url))
for (let n = 0; n < 1e10; n++) {
// Schleife zur Simulation von Arbeit.
}
} else {
// Diese Ausgabe wird durch die for-Schleife im Hauptthread blockiert.
console.log('foo')
}
'use strict'
const { Worker, isMainThread } = require('node:worker_threads')
if (isMainThread) {
new Worker(__filename)
for (let n = 0; n < 1e10; n++) {
// Schleife zur Simulation von Arbeit.
}
} else {
// Diese Ausgabe wird durch die for-Schleife im Hauptthread blockiert.
console.log('foo')
}
Starten von Worker-Threads aus Preload-Skripten
Seien Sie vorsichtig beim Starten von Worker-Threads aus Preload-Skripten (Skripte, die mit dem Befehlszeilenparameter -r
geladen und ausgeführt werden). Sofern die Option execArgv
nicht explizit gesetzt wird, übernehmen neue Worker-Threads automatisch die Befehlszeilenparameter vom laufenden Prozess und laden die gleichen Preload-Skripte wie der Hauptthread. Wenn das Preload-Skript bedingungslos einen Worker-Thread startet, wird jeder erzeugte Thread einen weiteren erzeugen, bis die Anwendung abstürzt.