Node.js工作线程共享对象/存储 [英] Nodejs worker threads shared object/store
问题描述
所以,我正在阅读一些有关nodejs的内容,当我遇到 Worker Threads .
So, I was reading some stuff regarding nodejs and I was amazed when I came across Worker Threads.
我认为拥有线程是一个很好的选择,尤其是将线程与共享内存访问结合使用时.您可能已经想过-> SharedArrayBuffer
...
Having threads in my opinion is a great plus especially if you combine it with shared memory access. As you might think already -> SharedArrayBuffer
...
是的,这就是我的想法.因此,我想到的第一件事就是对其进行一些测试,然后尝试实现一个简单的store
(目前是一个简单的对象),该线程将在线程之间共享.
Yeap that's what I thought. So The first thing that came into my mind was to give it a little test and try to implement a simple store
(a simple object for now) that would be shared among the threads.
问题是,(除非我在这里不见了什么)如何使用SharedArrayBuffer
使n个线程可访问一个对象?
The question is, (unless I'm missing something here) how can you make an object accessible from n threads with the use of SharedArrayBuffer
?
我知道对于一个简单的Uint32Array
是可行的,但是对于该对象该怎么办?
I know that for a simple Uint32Array
is doable, but regarding the object what can be done?
起初我想将其转换为Uint32Array
,就像您可能会看到的那样,但是即使查看该死的源代码也让我想哭...
At first I thought to convert it to a Uint32Array
as you may see bellow, but even looking at the damn source code makes me wanna cry...
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);
}
}
最后,nodejs 10.5.0中的线程之间共享对象,这可能吗?怎么样?
In conclusion, shared object among threads in nodejs 10.5.0, is it possible? how?
推荐答案
ECMA脚本不包含共享对象,但是具有SharedArrayBuffer.而且,您可以使用DataView和包装器直接在缓冲区中写入数据,从而实现这种行为:
ECMA Script contains no shared objects but it have SharedArrayBuffer. And you can implement such behavior on your own writing data directly in buffer using DataView and wrapper:
// Shared value
class SharedPoint {
constructor(array) {
this.dataview = new DataView(array);
}
set x(value) {
this.dataview.setUint8(0, value);
}
set y(value) {
this.dataview.setUint8(1, value);
}
get x() {
return this.dataview.getUint8(0);
}
get y() {
return this.dataview.getUint8(1);
}
}
// Usage
const buffer = new SharedArrayBuffer(2);
// Create two instances of shared point.
const point0 = new SharedPoint(buffer);
const point1 = new SharedPoint(buffer);
// Get initial values for point #1
console.log('x', point1.x); // 0
console.log('y', point1.y); // 0
// Update point #0
point0.x = 64;
point0.y = 32;
// Get changes in point #1
console.log('x', point1.x); // 64
console.log('y', point1.y); // 32
您可以创建可操纵字符串或类似C的结构的类类似C的结构一个>.虽然SharedArrayBuffer是可转移的对象,但它可以在工作进程和主进程之间共享.
You are able to create class which can manipulate strings or C-like structures. While SharedArrayBuffer is tranferable object it can be shared between worker and main process.
⚠️注意由于 Spectre攻击 SharedArrayBuffer已被所有主要浏览器禁用并重新启用从67版开始的Chrome中(如果可能).在我可以使用上查看浏览器支持.
⚠️ Note Due to Spectre attack SharedArrayBuffer was disabled by all major browsers and reenabled in Chrome since version 67 where it possible. Check browsers support on can i use.
这篇关于Node.js工作线程共享对象/存储的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!