doc: improve worker_threads documentation
This adds a few examples and clarifications. PR-URL: https://github.com/nodejs/node/pull/26110 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Anto Aravinth <anto.aravinth.cse@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
This commit is contained in:
parent
d1d9daba46
commit
70a500f3fd
@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
> Stability: 1 - Experimental
|
> Stability: 1 - Experimental
|
||||||
|
|
||||||
The `worker_threads` module enables the use of threads with message channels
|
The `worker_threads` module enables the use of threads that execute JS code
|
||||||
between them. To access it:
|
in parallel. To access it:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const worker = require('worker_threads');
|
const worker = require('worker_threads');
|
||||||
@ -58,6 +58,18 @@ added: v10.5.0
|
|||||||
|
|
||||||
Is `true` if this code is not running inside of a [`Worker`][] thread.
|
Is `true` if this code is not running inside of a [`Worker`][] thread.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const { Worker, isMainThread } = require('worker_threads');
|
||||||
|
|
||||||
|
if (isMainThread) {
|
||||||
|
// This re-loads the current file inside a Worker instance.
|
||||||
|
new Worker(__filename);
|
||||||
|
} else {
|
||||||
|
console.log('Inside Worker!');
|
||||||
|
console.log(isMainThread); // Prints 'false'.
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## worker.parentPort
|
## worker.parentPort
|
||||||
<!-- YAML
|
<!-- YAML
|
||||||
added: v10.5.0
|
added: v10.5.0
|
||||||
@ -72,6 +84,23 @@ using `worker.on('message')`, and messages sent from the parent thread
|
|||||||
using `worker.postMessage()` will be available in this thread using
|
using `worker.postMessage()` will be available in this thread using
|
||||||
`parentPort.on('message')`.
|
`parentPort.on('message')`.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const { Worker, isMainThread, parentPort } = require('worker_threads');
|
||||||
|
|
||||||
|
if (isMainThread) {
|
||||||
|
const worker = new Worker(__filename);
|
||||||
|
worker.once('message', (message) => {
|
||||||
|
console.log(message); // Prints 'Hello, world!'.
|
||||||
|
});
|
||||||
|
worker.postMessage('Hello, world!');
|
||||||
|
} else {
|
||||||
|
// When a message from the parent thread is received, send it back:
|
||||||
|
parentPort.once('message', (message) => {
|
||||||
|
parentPort.postMessage(message);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## worker.threadId
|
## worker.threadId
|
||||||
<!-- YAML
|
<!-- YAML
|
||||||
added: v10.5.0
|
added: v10.5.0
|
||||||
@ -91,6 +120,19 @@ added: v10.5.0
|
|||||||
An arbitrary JavaScript value that contains a clone of the data passed
|
An arbitrary JavaScript value that contains a clone of the data passed
|
||||||
to this thread’s `Worker` constructor.
|
to this thread’s `Worker` constructor.
|
||||||
|
|
||||||
|
The data is cloned as if using [`postMessage()`][`port.postMessage()`],
|
||||||
|
according to the [HTML structured clone algorithm][].
|
||||||
|
|
||||||
|
```js
|
||||||
|
const { Worker, isMainThread, workerData } = require('worker_threads');
|
||||||
|
|
||||||
|
if (isMainThread) {
|
||||||
|
const worker = new Worker(__filename, { workerData: 'Hello, world!' });
|
||||||
|
} else {
|
||||||
|
console.log(workerData); // Prints 'Hello, world!'.
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Class: MessageChannel
|
## Class: MessageChannel
|
||||||
<!-- YAML
|
<!-- YAML
|
||||||
added: v10.5.0
|
added: v10.5.0
|
||||||
@ -134,6 +176,20 @@ added: v10.5.0
|
|||||||
The `'close'` event is emitted once either side of the channel has been
|
The `'close'` event is emitted once either side of the channel has been
|
||||||
disconnected.
|
disconnected.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const { MessageChannel } = require('worker_threads');
|
||||||
|
const { port1, port2 } = new MessageChannel();
|
||||||
|
|
||||||
|
// Prints:
|
||||||
|
// foobar
|
||||||
|
// closed!
|
||||||
|
port2.on('message', (message) => console.log(message));
|
||||||
|
port2.on('close', () => console.log('closed!'));
|
||||||
|
|
||||||
|
port1.postMessage('foobar');
|
||||||
|
port1.close();
|
||||||
|
```
|
||||||
|
|
||||||
### Event: 'message'
|
### Event: 'message'
|
||||||
<!-- YAML
|
<!-- YAML
|
||||||
added: v10.5.0
|
added: v10.5.0
|
||||||
@ -156,6 +212,9 @@ Disables further sending of messages on either side of the connection.
|
|||||||
This method can be called when no further communication will happen over this
|
This method can be called when no further communication will happen over this
|
||||||
`MessagePort`.
|
`MessagePort`.
|
||||||
|
|
||||||
|
The [`'close'` event][] will be emitted on both `MessagePort` instances that
|
||||||
|
are part of the channel.
|
||||||
|
|
||||||
### port.postMessage(value[, transferList])
|
### port.postMessage(value[, transferList])
|
||||||
<!-- YAML
|
<!-- YAML
|
||||||
added: v10.5.0
|
added: v10.5.0
|
||||||
@ -166,9 +225,28 @@ added: v10.5.0
|
|||||||
|
|
||||||
Sends a JavaScript value to the receiving side of this channel.
|
Sends a JavaScript value to the receiving side of this channel.
|
||||||
`value` will be transferred in a way which is compatible with
|
`value` will be transferred in a way which is compatible with
|
||||||
the [HTML structured clone algorithm][]. In particular, it may contain circular
|
the [HTML structured clone algorithm][].
|
||||||
references and objects like typed arrays that the `JSON` API is not able
|
|
||||||
to stringify.
|
In particular, the significant differences to `JSON` are:
|
||||||
|
- `value` may contain circular references.
|
||||||
|
- `value` may contain instances of builtin JS types such as `RegExp`s,
|
||||||
|
`BigInt`s, `Map`s, `Set`s, etc.
|
||||||
|
- `value` may contained typed arrays, both using `ArrayBuffer`s
|
||||||
|
and `SharedArrayBuffer`s.
|
||||||
|
- `value` may contain [`WebAssembly.Module`][] instances.
|
||||||
|
- `value` may not contain native (C++-backed) objects other than `MessagePort`s.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const { MessageChannel } = require('worker_threads');
|
||||||
|
const { port1, port2 } = new MessageChannel();
|
||||||
|
|
||||||
|
port1.on('message', (message) => console.log(message));
|
||||||
|
|
||||||
|
const circularData = {};
|
||||||
|
circularData.foo = circularData;
|
||||||
|
// Prints: { foo: [Circular] }
|
||||||
|
port2.postMessage(circularData);
|
||||||
|
```
|
||||||
|
|
||||||
`transferList` may be a list of `ArrayBuffer` and `MessagePort` objects.
|
`transferList` may be a list of `ArrayBuffer` and `MessagePort` objects.
|
||||||
After transferring, they will not be usable on the sending side of the channel
|
After transferring, they will not be usable on the sending side of the channel
|
||||||
@ -182,6 +260,30 @@ from either thread. They cannot be listed in `transferList`.
|
|||||||
`value` may still contain `ArrayBuffer` instances that are not in
|
`value` may still contain `ArrayBuffer` instances that are not in
|
||||||
`transferList`; in that case, the underlying memory is copied rather than moved.
|
`transferList`; in that case, the underlying memory is copied rather than moved.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const { MessageChannel } = require('worker_threads');
|
||||||
|
const { port1, port2 } = new MessageChannel();
|
||||||
|
|
||||||
|
port1.on('message', (message) => console.log(message));
|
||||||
|
|
||||||
|
const uint8Array = new Uint8Array([ 1, 2, 3, 4 ]);
|
||||||
|
// This posts a copy of `uint8Array`:
|
||||||
|
port2.postMessage(uint8Array);
|
||||||
|
// This does not copy data, but renders `uint8Array` unusable:
|
||||||
|
port2.postMessage(uint8Array, [ uint8Array.buffer ]);
|
||||||
|
|
||||||
|
// The memory for the `sharedUint8Array` will be accessible from both the
|
||||||
|
// original and the copy received by `.on('message')`:
|
||||||
|
const sharedUint8Array = new Uint8Array(new SharedArrayBuffer(4));
|
||||||
|
port2.postMessage(sharedUint8Array);
|
||||||
|
|
||||||
|
// This transfers a freshly created message port to the receiver.
|
||||||
|
// This can be used, for example, to create communication channels between
|
||||||
|
// multiple `Worker` threads that are children of the same parent thread.
|
||||||
|
const otherChannel = new MessageChannel();
|
||||||
|
port2.postMessage({ port: otherChannel.port1 }, [ otherChannel.port1 ]);
|
||||||
|
```
|
||||||
|
|
||||||
Because the object cloning uses the structured clone algorithm,
|
Because the object cloning uses the structured clone algorithm,
|
||||||
non-enumerable properties, property accessors, and object prototypes are
|
non-enumerable properties, property accessors, and object prototypes are
|
||||||
not preserved. In particular, [`Buffer`][] objects will be read as
|
not preserved. In particular, [`Buffer`][] objects will be read as
|
||||||
@ -215,6 +317,9 @@ Starts receiving messages on this `MessagePort`. When using this port
|
|||||||
as an event emitter, this will be called automatically once `'message'`
|
as an event emitter, this will be called automatically once `'message'`
|
||||||
listeners are attached.
|
listeners are attached.
|
||||||
|
|
||||||
|
This method exists for parity with the Web `MessagePort` API. In Node.js,
|
||||||
|
it is only useful for ignoring messages when no event listener is present.
|
||||||
|
|
||||||
### port.unref()
|
### port.unref()
|
||||||
<!-- YAML
|
<!-- YAML
|
||||||
added: v10.5.0
|
added: v10.5.0
|
||||||
@ -465,12 +570,14 @@ Calling `unref()` on a worker will allow the thread to exit if this is the only
|
|||||||
active handle in the event system. If the worker is already `unref()`ed calling
|
active handle in the event system. If the worker is already `unref()`ed calling
|
||||||
`unref()` again will have no effect.
|
`unref()` again will have no effect.
|
||||||
|
|
||||||
|
[`'close'` event]: #worker_threads_event_close
|
||||||
[`Buffer`]: buffer.html
|
[`Buffer`]: buffer.html
|
||||||
[`EventEmitter`]: events.html
|
[`EventEmitter`]: events.html
|
||||||
[`EventTarget`]: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget
|
[`EventTarget`]: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget
|
||||||
[`MessagePort`]: #worker_threads_class_messageport
|
[`MessagePort`]: #worker_threads_class_messageport
|
||||||
[`SharedArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer
|
[`SharedArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer
|
||||||
[`Uint8Array`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array
|
[`Uint8Array`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array
|
||||||
|
[`WebAssembly.Module`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Module
|
||||||
[`Worker`]: #worker_threads_class_worker
|
[`Worker`]: #worker_threads_class_worker
|
||||||
[`cluster` module]: cluster.html
|
[`cluster` module]: cluster.html
|
||||||
[`inspector`]: inspector.html
|
[`inspector`]: inspector.html
|
||||||
|
Loading…
x
Reference in New Issue
Block a user