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

node child process: will it always terminate by itself?

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

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. 什么情况下会去'error'事件?

  2. 有没有可能子进程无法终止?如果是这样,什么时候会发生?

  3. 如果情况 2 发生,当我的主进程已经终止时,如何杀死这些子进程?

  1. 只要ls命令,子进程就会出错,或者进程出错。因此,如果 /user 不存在,则进程会出错,然后终止。当你在 Node 中生成一个子进程时,它的行为就像你在命令行中执行命令一样。大多数进程都会死于错误。这真的取决于。您必须阅读 linux 或 unix 或任何您正在使用的 OS 的文档,以了解发生错误时会发生什么。但是这些系统级命令应该死掉 对于像 ls 这样的简单命令,它是非常安全的。如果它出错,它就会死亡。结束.

  2. 子进程可能没有终止。很难准确地说出子进程何时不会终止。各种各样的事情都可能导致这种情况。例如,您 fork 了某个进程但从未关闭它,或者子进程由于某种原因陷入了某种无限循环。有些进程虽然已启动并且打算无限期地继续,但只能手动关闭。

  3. 如果情况 2 曾经发生,您有几种方法可以消除它。在该示例中,ls javascript 变量引用表示进程的对象。出于好奇,您可以将 ls 对象记录到命令行并查看其中的所有属性。所以一般来说,只要你调用spawn(),它就会returns给你这种子进程对象。在 Node 中,终止进程最简单的方法是在子进程对象上调用 kill() 函数。所以在这种情况下,你会调用 ls.kill(signal) 作为信号,你可以使用 'SIGINT''SIGTERM',我认为 'SIGHUP' 也可以。您可以阅读有关信号的更多信息 here

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

希望对您有所帮助。