Как изменить тот же массив, используя многопоточность в node js? - PullRequest
0 голосов
/ 10 июля 2020

Привет, кто-нибудь знает, как изменить один и тот же массив, используя 2 worker_threads в node js?

Я добавляю значение в рабочий поток 1 и вставляю его в рабочий поток 2, но рабочий поток 2 не может см. значение, добавленное 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 переменная в w2. js файл всегда имеет значение «2» вместо 250.

Ответы [ 2 ]

1 голос
/ 10 июля 2020

В node.js, чтобы разделить память между потоками, вам нужно выделить что-то вроде SharedArrayBuffer, к которому вы затем можете получить доступ из нескольких потоков. Объекты общих буферов распределяются по-разному, что позволяет получать к ним доступ нескольким потокам V8 в nodejs, тогда как обычные массивы не могут.

Затем вам нужно будет правильно управлять параллелизмом, чтобы вы не пытались обновлять данные одновременно из более чем одного потока (создавая условия гонки). В случаях, когда я использовал разделяемую память в node.js WorkerThreads, я разработал код таким образом, чтобы только один поток когда-либо имел доступ к общей памяти одновременно, и это один из способов решения проблем параллелизма. Есть также Atomics в node.js, которые позволяют вам «контролировать» доступ, так что только один поток обращается к нему за раз.

0 голосов
/ 10 июля 2020

РЕДАКТИРОВАТЬ: это явно устаревшее и неправильное. См. Комментарий ниже.

Вы не можете сделать это в javascript. Объекты в рабочие потоки передаются по значению. Это сделано намеренно, поэтому вам не нужно иметь дело с блокировками и всеми проблемами, которые возникают, когда несколько потоков могут изменять объект.

Способ решения этой проблемы в javascript - отправить результат работы через канал сообщения (опять же, по значению).

Итак, если вы хотите продолжить обработку этого объекта, вы можете передать его по каналу сообщения от рабочего 1 к работнику 2.

Или если у вас есть рабочий пул, вы можете передавать сообщения в основной поток и добавлять их, например, в массив результатов.

...