当父进程死亡时,Node.JS子进程会被终止

17

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

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

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

1个回答

28

你需要设置detached选项

如果设置了detached选项,子进程将成为新进程组的领导者。这使得子进程能够在父进程退出后继续运行。

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

3
非常感谢。不知道我怎么会错过那个。供参考,如果其他人也觉得这个答案有用,这是手册上的链接:https://nodejs.org/api/child_process.html#child_process_options_detached - JHH
1
我有一个疑虑。手册 - 以及您的代码 - 明确指出,为了使进程在后台继续运行,stdio必须被定向到除父进程(默认)之外的其他地方。然而,我发现即使我没有指定任何stdio选项,该进程实际上仍然会在我杀死我的节点服务器后继续运行。我不确定这里到底发生了什么,但也许['ignore','ignore','ignore']仍然是一个明智的选择。 - JHH
2
不指定stdio将默认为stdio:['pipe','pipe','pipe']...这意味着管道可以通过ChildProcess.stdin,ChildProcess.stdout和ChildProcess.stderr使用(在这种情况下我认为您必须从stdout和stderr读取,否则您的childprocess可能会挂起)...如果您不需要与父进程交互的childprosess的stdio,则可以只使用“ignore”,它将转发来自childprocess的任何输出到/dev/null。 - Johny
感谢提供额外的信息,非常感激。现在我已经成功地让它运行良好了。 - JHH
但是你又该如何将实际数据传递给子进程呢?如果使用“ignore”来处理标准输入流,则子进程的stdin属性为未定义,我们无法手动写入它。 - Herman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接