How to modify the same array using multi thread in node js?

Viewed 1513

Hi does anyone know how to modify a same array by using 2 worker_threads in node js?

I add value in worker thread 1 and pop it in worker thread 2, but worker thread 2 can't see the value added by 1.

//in a.js
const {isMainThread, parentPort, threadId, MessageChannel, Worker} = require('worker_threads');

global.q = [1,2];

exports.setter_q= function(value){
    q.push(value);}

exports.getter_q=function(value){
  var v=q.pop()
  return v;
}

if(isMainThread) {
    var workerSche=new Worker("./w1.js")
    var workerSche1=new Worker("./w2.js")
}
//in w1.js
const {isMainThread, parentPort, threadId, MessageChannel, Worker} = require('worker_threads');

if(isMainThread){
    // do something
} else{
    var miniC1=require("./a.js")
    miniC1.setter_q(250);

    // do something
}
//in w2.js
const {isMainThread, parentPort, threadId, MessageChannel, Worker} = require('worker_threads');

if(isMainThread){
    // do something
} else{
    var miniC1=require("./a.js")
    var qlast=miniC1.getter_q();
    // do something
}

qlast variable in w2.js file is always value '2' instead of 250.

2 Answers

In node.js, to share memory between threads, you have to allocate something like a SharedArrayBuffer that you can then access from multiple threads. The shared buffer objects are allocated differently that allows them to be accessed by multiple V8 threads in nodejs whereas regular arrays cannot.

You will then have to manage concurrency properly so you aren't attempting to update the data simultaneously from more than one thread (creating race conditions). In the cases where I've used shared memory in node.js WorkerThreads, I've designed the code so that only one thread ever had access to the shared memory at once and that is one way of solving concurrency issues. There are also Atomics in node.js that allow you to "control" access such that only one thread is accessing it at a time.

EDIT: This is apparently outdated and wrong. See comment below.

You can't do that in javascript. Objects to worker threads are passed by value. This is by design so you don't have to deal with locking and all the problems that come when multiple threads can mutate an object.

The way to solve this problem in javascript is to send the work result via a message channel (again, by value).

So if you wanted to further process that object, you could pass it in a message channel from worker 1 to worker 2.

Or if you have a worker pool, you could pass messages to the main thread and add them to a result array there for example.

Related