【问题标题】:How to listen terminate signal from worker in nodejs?如何在nodejs中监听来自worker的终止信号?
【发布时间】:2020-08-22 09:38:41
【问题描述】:

我有一个使用worker_threads 生成一个新线程的主进程。在某些特殊情况下,主进程必须关闭这个线程,而不管它是否完成了任务,所以 MainThread 使用terminate() 来停止线程。但是,此线程会产生不同的依赖项,这些依赖项需要在退出之前关闭。这些依赖必须从线程中关闭,所以我不能使用worker.on('exit'),因为它是在主进程上运行的。

有没有办法从工作人员本身监听终止?

我想要实现的一些最小示例。

const {Worker, isMainThread} = require('worker_threads');

if (isMainThread) {
  const worker = new Worker(__filename);
  worker.on('message', console.log);
  worker.on('error', console.log);
  worker.on('exit', console.log);

  setTimeout(() => {
    console.log('Worker is gonna be terminated');
    worker.terminate();
  }, 5000);
} else {
  (async () => {
    console.log('I am the worker');
    // This thread will spawn its own dependencies, so I want to listen here the terminate signal from 
    // mainThread to close the dependencies of this worker
    // Sth like the following will be awesome
    // thread.on('exit', () => { /* close dependencies */ })

    // Simulate a task which takes a larger time than MainThread wants to wait
    await new Promise(resolve => {
      setTimeout(resolve, 10000);
    });
  })();
}

【问题讨论】:

  • 终止执行函数worker.emit('exit')。然后,你可以在worker.on('exit', console.log);上收听它;
  • @Amn 是的,但我需要听取工人本身的意见。 worker.on('exit', console.log) 仅在父进程中可用。

标签: node.js multithreading node-worker-threads


【解决方案1】:

您可以通过worker.postMessage(value)/parentPort.on("message", (value) => {...})向工作线程发出退出信号,然后在工作线程中使用process.exit()。当然要先清理。

我建议使用value 的对象,这样您就可以将多个命令或日期从主线程传递到工作线程。

const { Worker, isMainThread, parentPort } = require("worker_threads");

if (isMainThread) {
  const worker = new Worker(__filename);
  worker.on("message", console.log);
  worker.on("error", console.log);
  worker.on("exit", console.log);

  setTimeout(() => {
    console.log("Worker is gonna be terminated");
    // replace worker.terminate(); with something like
    worker.postMessage({ exit: true });
    // maybe add another setTimeout with worker.terminate() just in case?
  }, 5000);
} else {
  (async () => {
    // listen for message and do things according to passed value
    parentPort.on("message", (value) => {
      // worker threads do not have multiple listeners available for passing different event,
      // therefore add one onMessage listener, and pass an object with commands/data from main thread
      if (value.exit) {
        // clean up
        console.log("doing cleanup");
        process.exit(0);
      }
    });
    // add other logic for receiving messages from main thread

    console.log("I am the worker");
    // This thread will spawn its own dependencies, so I want to listen here the terminate signal from
    // mainThread to close the dependencies of this worker
    // Sth like the following will be awesome
    // thread.on('exit', () => { /* close dependencies */ })

    // Simulate a task which takes a larger time than MainThread wants to wait
    await new Promise((resolve) => {
      setTimeout(resolve, 10000);
    });
  })();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多