节点子进程:它总是自动终止吗?

时间:2016-09-16 03:40:28

标签: node.js child-process

我有代码来生成这样的子进程:

const spawn = require('child_process').spawn;
const ls = spawn('ls', ['-lh', '/usr'], {
    detached: true
});

ls.stdout.on('data', (data) => {
  console.log(`stdout: ${data}`);
});

ls.stderr.on('data', (data) => {
  console.log(`stderr: ${data}`);
});

ls..on('error', (data) => {
  console.log(`error: ${data}`);
});

ls.on('close', (code) => {
  console.log(`child process exited with code ${code}`);
});

直到现在,我可以控制来自stdout和stderr的消息,并在完成任务后自动退出。

我的问题是:

  1. 在什么情况下会进入'错误'事件?

  2. 子进程是否可能无法终止?如果是的话,什么时候会发生?

  3. 如果案例2发生,当主要流程已经终止时,如何终止这些子流程?

1 个答案:

答案 0 :(得分:4)

  1. 只要ls命令或进程错误,子进程就会出错。因此,如果/user不存在,那么该过程会出错,然后就会死亡。当您在Node中生成子进程时,它的行为方式与在命令行中执行该命令的方式相同。大多数进程都会因错误而死亡。这真的只是取决于。您必须阅读l​​inux或unix的文档或您正在使用的任何操作系统,以查看错误发生时会发生什么。但是这些系统级命令应该死掉对于像ls这样的简单命令,它非常安全。如果错误,它就会死亡。结束。

  2. 子进程可能无法终止。很难确切地说儿童过程何时不能终止。各种各样的事情可能会导致这种情况例如,你分叉了一些进程,但从未关闭它,或者如果由于某种原因子进程陷入某种无限循环。虽然某些流程已启动并且无限期地继续,但只能手动关闭。

  3. 如果案例2发生,你有几种方法可以杀死它。在示例中,ls javascript变量引用表示进程的对象。出于好奇,您可以将ls对象记录到命令行并查看其中的所有属性。所以一般来说,每当你调用spawn()时,它都会返回给你这种子进程对象。在Node中,最简单的方法是调用子进程对象上的kill()函数。因此,在这种情况下,您可以致电ls.kill(signal)对于信号,您可以使用'SIGINT''SIGTERM',我认为'SIGHUP'也可以。您可以阅读有关信号here的更多信息。

  4. 但是,您询问了如果主进程已经终止,如何终止子进程。为此,您必须使用命令行。如果您知道流氓子进程的进程ID,则只需运行kill <pid>,其中pid是进程ID。您可以从子进程对象获取进程ID。如果您不知道pid并且无法获取它,那么您可以运行ps -eaf,这将打印出计算机上当前正在运行的所有进程的列表,这很多。因此,为了帮助您找到所需的流程,您可以执行ps -eaf | grep <process-name>,这可能有助于您找到流程。例如,如果在这种情况下ls命令没有死亡,这实际上不会发生,我可以做ps -eaf | grep ls,这很可能找到正确的过程和进程ID。然后,您可以运行kill <pid>

    希望这有帮助。

相关问题