所以,我正在阅读有关Node.js的一些内容,当我遇到Worker Threads时,我感到非常惊讶。
在我看来,拥有线程是一个很大的优势,特别是如果你将它与共享内存访问相结合。正如你可能已经想到的 -> SharedArrayBuffer
...
是的,这就是我想到的。所以我脑海中首先想到的是进行一些简单的测试,并尝试实现一个简单的store
(目前只是一个简单的对象),该对象将在线程之间共享。
问题是,(除非我在这里漏掉了什么)如何使用SharedArrayBuffer
使对象能够从n个线程中访问?
我知道对于一个简单的Uint32Array
是可行的,但是对于对象,可以做些什么呢?
起初,我想将其转换为Uint32Array
,就像下面所示,但甚至看着该死的源代码也让我想哭...
const {
Worker,
isMainThread,
workerData
} = require('worker_threads');
const store = {
ks109: {
title: 'some title 1',
description: 'some desciption 1',
keywords: ['one', 'two']
},
ks110: {
title: 'some title 2',
description: 'some desciption 2',
keywords: ['three', 'four']
},
ks111: {
title: 'some title 3',
description: 'some desciption 3',
keywords: ['five', 'six']
}
}
const shareObject = (obj) => {
let OString = JSON.stringify(obj);
let SABuffer = new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * OString.length);
let sArray = new Int32Array(SABuffer);
for (let i = 0; i < OString.length; i++) {
sArray[i] = OString.charCodeAt(i);
}
return sArray;
}
if (isMainThread) {
const sharedStore = shareObject(store);
console.log('[Main][Data Before]:', sharedStore.slice(-10));
let w = new Worker(__filename, {
workerData: sharedStore
});
w.on('message', (msg) => {
console.log(`[Main][Thread message]: ${msg}`);
});
w.on('error', (err) => {
console.error(`[Main][Thread error] ${err.message}`);
});
w.on('exit', (code) => {
if (code !== 0) {
console.error(`[Main][Thread unexpected exit]: ${code}`);
}
});
setInterval(() => {
// At some point you ll see a value change,
// it's 'six' becoming 'sax' (big time!)
console.log('[Main][Data Check]:', sharedStore.slice(-10));
}, 1000);
} else {
let str = String.fromCharCode.apply(this, workerData);
let obj = JSON.parse(str);
obj.ks111.keywords[1] = 'sax'; // big time!
let OString = JSON.stringify(obj);
for (let i = 0; i < OString.length; i++) {
workerData[i] = OString.charCodeAt(i);
}
}
总之,在Node.js 10.5.0中,线程之间是否可以共享对象?如何实现?
SharedArrayBuffer
,它只包含原始二进制数据(而不是对象)。因此,我不知道如何在线程之间直接共享对象。工作线程似乎类似于浏览器中的Web Worker,在那里没有共享常规变量,它们必须通过postMessage()
与其他代码通信(出于同步原因)。 - jfriend00SharedArrayBuffer
中似乎并没有太大的帮助,除了共享一个字符串。每个工作线程都必须将 JSON 解析为自己独立的非共享对象。这种级别的共享可以通过向每个工作线程发布消息来完成,以便在任何人想要更改数据时,所有工作线程都有相同的数据副本。 - jfriend00