【问题标题】:How to kill all child processes on exit?如何在退出时杀死所有子进程?
【发布时间】:2013-03-27 19:35:48
【问题描述】:

node.js 进程退出时如何杀死所有子进程(使用 child_process.spawn 生成)?

【问题讨论】:

标签: node.js


【解决方案1】:

添加到@robertklep 的答案:

如果像我一样,你想在 Node 被外部杀死时这样做,而不是它自己的选择,你必须对信号做一些诡计。

关键是监听你可能被杀死的任何信号,并调用process.exit(),否则默认情况下Node不会在process上发出exit

var cleanExit = function() { process.exit() };
process.on('SIGINT', cleanExit); // catch ctrl-c
process.on('SIGTERM', cleanExit); // catch kill

这样做之后,你就可以在process上正常收听exit了。

唯一的问题是无法捕获SIGKILL,但这是设计使然。无论如何,你应该是 killing 和 SIGTERM(默认值)。

请参阅this question 了解更多信息。

【讨论】:

    【解决方案2】:

    我认为唯一的方法是保留对spawn返回的ChildProcess对象的引用,并在退出主进程时将其杀死。

    一个小例子:

    var spawn     = require('child_process').spawn;
    var children  = [];
    
    process.on('exit', function() {
      console.log('killing', children.length, 'child processes');
      children.forEach(function(child) {
        child.kill();
      });
    });
    
    children.push(spawn('/bin/sleep', [ '10' ]));
    children.push(spawn('/bin/sleep', [ '10' ]));
    children.push(spawn('/bin/sleep', [ '10' ]));
    
    setTimeout(function() { process.exit(0) }, 3000);
    

    【讨论】:

    • 在我的 Mac 上,当主节点进程完成时,任何由 spawn 启动的子进程都会被杀死。也许这是特定于操作系统的?
    • 在我的 Mac (10.8.3) 上它们继续运行:使用上面的代码,当我注释掉 child.kill() 时,我短暂地(直到 10 秒结束)看到三个 sleep 进程主进程停止后ps 的输出(尽管这些进程连接到 shell 的控制器终端;当我杀死 shell 时,它们就消失了)。
    • 有趣。我的子进程是一个 phantomjs 进程。也许这表现不同。如果上面的代码发生变化,我将使用它。 (10.8.0)
    • @Sukima the fine manual 声明:“向已经退出的子进程发送信号不是错误,但可能会产生无法预料的后果:如果 PID(进程 ID)已重新分配给另一个进程,信号将被传递给该进程”。所以是的,它可能杀死一个不相关的进程。
    • @robertklep 我就是这么想的。听起来很糟糕。在上面的代码示例中对防止这种情况有什么建议吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-17
    • 2019-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多