【问题标题】:Node.JS child processes being killed when parent diesNode.JS 子进程在父进程死亡时被杀死
【发布时间】:2015-06-08 12:08:50
【问题描述】:

我正在使用 child_process.spawn() 从我在 Ubuntu 上运行的 Node.JS 应用程序启动一个脚本。据我所知,标准分叉或派生的 *nix 进程通常不会在父进程死亡时死亡,但是当从 Node.JS 派生进程时,它们似乎在我的应用程序崩溃时被杀死,或者被 ctrl-c 等中止.

为什么会这样,有没有办法解决这个问题?我似乎在 child_process API 中找不到任何明显的选项。

我的应用程序启动了一些应该在后台运行的长时间运行的任务,如果我的节点服务器崩溃或由于其他原因重新启动,我不想中断任务,而是希望节点服务器来备份并优雅地恢复监控这些正在运行的任务的进度。

【问题讨论】:

    标签: linux node.js child-process


    【解决方案1】:

    你需要设置分离选项

    如果设置了分离选项,子进程将成为 新流程组的负责人。这使得孩子可以 父级退出后继续运行。

    var child = spawn('prg', [], {
       detached: true,
       stdio: [ 'ignore', out, err ]
     });
    

    【讨论】:

    • 非常感谢。不知道我是怎么错过的。作为参考,如果其他人发现此答案有用,请参考手册:nodejs.org/api/…
    • 我有一个担心。手册 - 以及您的代码 - 特别说明 stdio 必须指向其他地方,而不是父进程(这是默认值),以便进程在后台继续。但是,我发现即使我没有指定任何 stdio 选项,即使在我杀死我的节点服务器之后,该过程实际上也会继续。我不确定这里到底发生了什么,但也许 ['ignore', 'ignore', 'ignore'] 仍然是一个明智的选择。
    • 不指定 stdio 将默认为 stdio: ['pipe', 'pipe', 'pipe']... 这意味着管道可通过 ChildProcess.stdin、ChildProcess.stdout 和 ChildProcess.stderr 获得(在这种情况下我认为您必须从 stdout 和 stderr 读取,否则您的子进程可能会挂起)...如果您不需要从父进程与 childprosess 的 stdio 交互,那么您可以使用'ignore' 会将子进程的任何输出转发到 /dev/null
    • 感谢您提供更多信息。赞赏。我现在运行良好。
    • 但是你如何将实际数据输入到子进程中呢?如果你对标准输入使用“忽略”,那么 child.stdin 属性是未定义的,我们不能手动写入。