-
Notifications
You must be signed in to change notification settings - Fork 0
JS worker threads
Why threads?
- Move heavy or slow or unpredictable processing to a parallel thread, so that it doesn't interrupt important things (e.g. VR rendering) in the main thread.
- Less expensive and less complex to share memory than when using
fork()
to a new process
-
Data passed to worker is copied, not shared -- with a couple of exceptions (see below)
const { Worker } = require('worker_threads')
const worker = new Worker('./myworker.js', { workerData: "any simple JS data here" });
worker.on('message', msg => console.log(msg));
worker.on('error', err => console.error(err));
worker.on('exit', code => {
if (code !== 0) console.error(`Worker stopped with exit code ${code}`)
else console.log("worker done")
});
worker.postMessage("hi")
And myworker.js:
const { workerData, parentPort } = require('worker_threads')
console.log("hello from worker", workerData)
parentPort.postMessage({ msg: "hello "+workerData })
parentPort.on("message", msg => console.log(msg))
Alternatively, rather than running a file you can run code directly using new Worker(code, { eval: true, workerData:... })
Normally, the workerData
is copied when a thread starts. It can contain any JSON valid data, and also even recursive structures and binary arrays, but they will be copied.
If you want to share binary data (only binary data) you can use SharedArrayBuffer
:
let sab = new SharedArrayBuffer(bytesize)
let floats = new Float32Array(sab); // etc.
const worker = new Worker(script, {workerData: floats})
Now this array of floats can be read & written from both threads.
Frustratingly, support for SharedArrayBuffer doesn't seem to be part of the C N-API just yet. That means we can't share binary data directly between both C++ addon modules and multiple workers. A workaround perhaps would be using a common external_arraybuffer defined in a C++ module and used by both workers.
See also Atomics.wait
/Atomics.notify