在 NodeJS 中执行 Ctrl-C 时优雅地结束子进程

Hat*_*ori 5 sigint child-process node.js

我有一个架构,其中一个父级生成一个子级,如下所示:

this.process = child.spawn(this.cmd, this.args);

this.process.on('exit', (code: number, signal: string) => {
    this.exitCode = code;
    console.log(`exit code: ${code}`);
});
Run Code Online (Sandbox Code Playgroud)

没有特别的选择,因为我想与孩子保持联系。因此,当我按 Ctr-C 杀死父级时,它会捕获SIGINT(1)结束子级,(2)正确退出。但SIGINT也会传播给孩子,因此父母无法优雅地结束它。那么,有没有办法做到这一点呢?也许是通过防止SIGINT传播给孩子?或者告诉孩子忽略这个信号?

我知道通过添加选项detached: truestdio: 'ignore'生成时可以做一些事情,但我不想这样做,因为如果父级死亡,我最终会遇到僵尸进程。而保留链接可以确保如果父母意外死亡,孩子也会被杀死。最后,我想避免让SIGINT孩子陷入困境,因为我想让他保持沉默。

编辑:父级已经有 aprocess.on('SIGINT', () => { ... }并且子级在 python 中。

jus*_*ase 5

您可以捕获这样的退出代码:

process.on('SIGINT', () => {
  // handle it yourself
})
Run Code Online (Sandbox Code Playgroud)

您可以将其传播给孩子,如下所示:

process.on('SIGINT', () => {
  this.child.kill('SIGINT')
})
Run Code Online (Sandbox Code Playgroud)

子进程当然也可以选择处理信号,明智的做法是不要仅仅因为您发送了单个信号就假设子进程将退出。您可能需要设置超时并发送重复或不同的信号才能完全终止进程。在继续之前,您还需要收听'exit'子进程的消息,以了解其实际何时被终止。

文档

  • 问题是“SIGINT”被发送到整个组。这对孩子也意味着。我实际上已经有了 `process.on('SIGINT', () => { //end child }` 但它不会阻止子进程独立接收 `SIGINT`。此外,`spawn` 函数返回子进程。所以,在给定的代码中,如果我添加 `this.process.on('SIGINT', () => { //do some }`,我希望子进程也能捕获 `SIGINT`。但是它事实并非如此。而且(通过阅读)看来,孩子需要脱离父母才能工作。但我不希望这样。 (2认同)