gpt4 book ai didi

Node.js 工作线程共享对象/存储

转载 作者:IT老高 更新时间:2023-10-28 23:26:48 27 4
gpt4 key购买 nike

所以,我正在阅读一些关于 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 中的线程间共享对象,有可能吗?怎么样?

最佳答案

ECMA 脚本不包含共享对象,但它有 SharedArrayBuffer .您可以使用 DataView 和包装器在自己的缓冲区中直接写入数据来实现这种行为:

// 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-like structures 的类.而SharedArrayBuffer是可转移的对象,它可以在工作进程和主进程之间共享。

⚠️ Note Due to Spectre attack SharedArrayBuffer was disabled by all major browsers and reenabled. Though the API is mature, its' support could be lower than one might expect. Check browsers support at can i use.

关于Node.js 工作线程共享对象/存储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51053222/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com