【问题标题】:Node.js: how to check if spawned process was successfully killedNode.js:如何检查生成的进程是否被成功杀死
【发布时间】:2020-11-14 02:41:21
【问题描述】:

我正在尝试停止在 Node.js 中生成的进程。我的DownloaderWrapper 类可以生成并使用一些不同的下载器应用程序,可以通过更改环境变量DOWNLOADER_PATH 来替换它们。但是,我注意到根据正在使用的下载器应用程序,它不会响应stop 函数发送的SIGKILL 信号并继续运行。

有什么方法可以确保停止生成的进程?或者如果我不能,我能否检测到进程是否未能停止并在我的stop 函数中返回'failed'

在 Windows 上测试。

export default class DownloaderWrapper {
    constructor() {
        this.process;
    }

    async download(spawnArgs) {
        if (!process) {
            this.process = spawn(process.env.DOWNLOADER_PATH, spawnArgs, { windowsHide: true });
        }
    }

    async stop() {
        if (this.process) {
            this.process.kill('SIGKILL');
            return new Promise(resolve => {
                this.process.on('close', (code, signal) => {
                    console.log(`child process terminated due to receipt of signal "${signal}"`);
                    resolve('stopped');
                });
            });
        } else {
            return 'stopped';
        }
    }
}

【问题讨论】:

  • 根据 signal(7) 手册页,您所说的事情不应该是可能的:“信号 SIGKILL 和 SIGSTOP 不能被捕获、阻止或忽略。”但是,我不确定我是否理解。您是否正在生成一个进程,然后生成另一个进程,该进程是某个下载程序?
  • 我的脚本可以生成一个下载器进程。下载程序进程可能会生成另一个进程,但我确信我会在此之前发出SIGKILL 信号。下载器进程只从我的脚本中生成。
  • 等一下,您似乎正在返回新的 Promise,其中包含在进程被终止时解析的侦听器,但是您在返回它之前已经终止了该进程,所以它永远不会捕获 '关闭'事件。
  • 使用 taskkill 杀死 Windows 上的进程对所有生成的进程都有效。 stackoverflow.com/questions/23706055/…

标签: javascript node.js


【解决方案1】:

尝试将您的停止功能更改为:

function stop() {
    return new Promise((resolve, reject) => {
       if (this.process) {
           this.process.on('exit', (code) => {
               resolve('stopped with code ' + code);
           });
           this.process.kill('SIGKILL');
       } else {
           reject('no process running');
       }
    });
}

// eg
stop().then((result) => {
    console.log(result);
}).catch((err) => {
    console.error(err);
});

我可能是错的,但我认为没有必要将你的停止函数定义为异步,因为无论如何你都会返回一个 Promise。在您的原始代码中,您在添加侦听器之前终止了该进程。此外,我在 NodeJS 官方文档中找不到关于名为“close”的 Process.on 侦听器的文档,这就是为什么我在代码中用 process.on('exit') 替换它的原因。希望其中一些事情可以解释为什么您没有看到任何证据表明您的进程正在被杀死,因为它没有被杀死,即使是这样,您也不会看到消息,因为没有关闭这样的事件。

另外,按照这段代码的方式,在进程被杀死后,你还有一个Process对象存储在this.process中。如果你再次调用 stop() 函数,那么 if(this.process) 仍然为真,它会再次尝试终止它。您可能希望在杀死它后将 this.process 设置为 null 或 undefined,具体取决于您的用例。

【讨论】:

    猜你喜欢
    • 2017-07-28
    • 1970-01-01
    • 2012-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多