Home > OS >  The result appears suddenly in multithreads nodjs worker
The result appears suddenly in multithreads nodjs worker

Time:11-26

The result appears suddenly. I put three consoles. The first one works properly. The rest suddenly appears at the end.

I want it to show when it reaches 200000000 and then when it reaches 300000000. but Now 200000000 and 300000000 suddenly appear at end of program

'use strict';
const { Worker, isMainThread, parentPort, workerData } = require('worker_threads');
const min = 2;
let primes = [];
const mystring = 1  ;
function generatePrimes(mystr, range) {
   for (let i = 0; i < 1000000000; i  ) {
       if (i===100000000){
         console.log(i);
       }
       
         if (i==200000000){
           
           console.log(i);
       }
       
          if (i==300000000){
           
           console.log(i);
       }
        mystr  
  }
             
}

if (isMainThread) {
  
  const threadCount =2;
  const threads = new Set();;
  console.log(`Running with ${threadCount} threads...`);
  const range = Math.ceil((max - min) / threadCount);
  let start = min;
  for (let i = 0; i < threadCount ; i  ) {
   
    threads.add(new Worker(__filename, { workerData: { start: mystring, range }}));
    start  = range;
  }
 // threads.add(new Worker(__filename, { workerData: { start, range: range   ((max - min   1) % threadCount)}}));
  for (let worker of threads) {
    worker.on('error', (err) => { throw err; });
    worker.on('exit', () => {
      threads.delete(worker);
      console.log(`Thread exiting, ${threads.size} running...`);
      if (threads.size === 0) {
        console.log(primes.join('\n'));
      }
    })
    worker.on('message', (msg) => {
      primes = primes.concat(msg);
    });
  }
} else {
  generatePrimes(workerData.start, workerData.range);
  parentPort.postMessage(primes);
}

CodePudding user response:

In the Doc's there is this -> https://nodejs.org/api/worker_threads.html#synchronous-blocking-of-stdio

Two solutions to this I can think off.

  1. send a message from the worker thread to the main thread and log from there.

  2. Make the primes function async, and put some async stuff in there, eg. setTimeout. This allows the worker threads message pump to continue running and allowing the main threads console to continue..

Below is your code modified to use option 1.

const { Worker, isMainThread, parentPort, workerData } = require('worker_threads');
const min = 2;
const max = 2;
let primes = [];
const mystring = 1  ;


async function generatePrimes(mystr, range) {
   for (let i = 0; i < 1000000000; i  ) {
       if (i===100000000){
          parentPort.postMessage({log: i});               }       
       if (i==200000000){   
          parentPort.postMessage({log: i});        
       }       
       if (i==300000000){           
          parentPort.postMessage({log: i});               }
       mystr  
  }             
}


if (isMainThread) {
  const threadCount =2;
  const threads = new Set();;
  console.log(`Running with ${threadCount} threads...`);
  const range = Math.ceil((max - min) / threadCount);
  let start = min;
  for (let i = 0; i < threadCount ; i  ) {   
    threads.add(new Worker(__filename, { workerData: { start: mystring, range }}));
    start  = range;
  }
 // threads.add(new Worker(__filename, { workerData: { start, range: range   ((max - min   1) % threadCount)}}));
  for (let worker of threads) {
    worker.on('error', (err) => { throw err; });
    worker.on('exit', () => {
      threads.delete(worker);
      console.log(`Thread exiting, ${threads.size} running...`);
      if (threads.size === 0) {
        console.log(primes.join('\n'));
      }
    })
    worker.on('message', (msg) => {
      if (msg.log) console.log(msg.log)
      else if (msg.primes) primes = primes.concat(msg.primes);
    });
  }
} else {
  generatePrimes(workerData.start, workerData.range);
  parentPort.postMessage({primes});
}

Below is your code modified to use option 2.

const { Worker, isMainThread, parentPort, workerData } = require('worker_threads');
const min = 2;
const max = 2;
let primes = [];
const mystring = 1  ;

const sleep = ms => new Promise(r => setTimeout(r, ms));

async function generatePrimes(mystr, range) {
  for (let i = 0; i < 1000000000; i  ) {
    if (i===100000000){
      console.log(i);
      await sleep(1);
    }       
    if (i==200000000){           
      console.log(i);
      await sleep(1);
    }       
    if (i==300000000){           
      console.log(i);
      await sleep(1);
    }
    mystr  
  }             
}


if (isMainThread) {
  const threadCount =2;
  const threads = new Set();;
  console.log(`Running with ${threadCount} threads...`);
  const range = Math.ceil((max - min) / threadCount);
  let start = min;
  for (let i = 0; i < threadCount ; i  ) {   
    threads.add(new Worker(__filename, { workerData: { start: mystring, range }}));
    start  = range;
  }
 // threads.add(new Worker(__filename, { workerData: { start, range: range   ((max - min   1) % threadCount)}}));
  for (let worker of threads) {
    worker.on('error', (err) => { throw err; });
    worker.on('exit', () => {
      threads.delete(worker);
      console.log(`Thread exiting, ${threads.size} running...`);
      if (threads.size === 0) {
        console.log(primes.join('\n'));
      }
    })
    worker.on('message', (msg) => {
      primes = primes.concat(msg);
    });
  }
} else {
  generatePrimes(workerData.start, workerData.range);
  parentPort.postMessage(primes);
}
  • Related