Node.js 多线程完全指南总结

2020-06-17 06:09:52易采站长站整理

具体来说 thread workers 更轻量,并且与其父线程共享相同的进程 ID。它们还可以与父线程共享内存,这样可以避免对大的数据负载进行序列化,从而更有效地来回传递数据。

现在让我们看一下如何在线程之间共享内存。为了共享内存,必须将

ArrayBuffer
SharedArrayBuffer
的实例作为数据参数发送到另一个线程。

这是一个与其父线程共享内存的 worker:


import { parentPort } from 'worker_threads';

parentPort.on('message', () => {
const numberOfElements = 100;
const sharedBuffer = new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * numberOfElements);
const arr = new Int32Array(sharedBuffer);

for (let i = 0; i < numberOfElements; i += 1) {
arr[i] = Math.round(Math.random() * 30);
}

parentPort.postMessage({ arr });
});

首先,我们创建一个

SharedArrayBuffer
,其内存需要包含100个32位整数。接下来创建一个
Int32Array
实例,它将用缓冲区来保存其结构,然后用一些随机数填充数组并将其发送到父线程。

在父线程中:


import path from 'path';

import { runWorker } from '../run-worker';

const worker = runWorker(path.join(__dirname, 'worker.js'), (err, { arr }) => {
if (err) {
return null;
}

arr[0] = 5;
});

worker.postMessage({});

arr [0]
的值改为
5
,实际上会在两个线程中修改它。

当然,通过共享内存,我们冒险在一个线程中修改一个值,同时也在另一个线程中进行了修改。但是我们在这个过程中也得到了一个好处:该值不需要进行序列化就可以另一个线程中使用,这极大地提高了效率。只需记住管理数据正确的引用,以便在完成数据处理后对其进行垃圾回收。

共享一个整数数组固然很好,但我们真正感兴趣的是共享对象 —— 这是存储信息的默认方式。不幸的是,没有

SharedObjectBuffer
或类似的东西,但我们可以自己创建一个类似的结构。

transferList参数

transferList
中只能包含
ArrayBuffer
MessagePort
。一旦它们被传送到另一个线程,就不能再次被传送了;因为内存里的内容已经被移动到了另一个线程。

目前,还不能通过

transferList
(可以使用