Node.js工作线程共享对象/存储 [英] Nodejs worker threads shared object/store

查看:793
本文介绍了Node.js工作线程共享对象/存储的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我正在阅读一些有关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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆