节点子进程:它是否总是自己终止?



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

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或您正在使用的任何操作系统的文档,以了解发生错误时会发生什么。但是这些系统级命令应该死亡,对于像ls这样的简单命令,它是相当安全的。如果出错,它就会死亡。最后。

  2. 有可能子进程没有终止。很难确切地说子进程何时不会终止。各种各样的事情都可能导致这种情况。例如,您分叉了某个进程,但从未关闭它,或者子进程由于某种原因陷入无限循环。

  3. 有些进程已经启动并打算无限期地继续,只能手动关闭。
  4. 如果情况2发生了,你有几种方法可以消除它。在这个例子中,ls javascript变量引用了一个表示进程的对象。出于好奇,您可以将ls对象记录到命令行,并查看其中的所有属性。所以一般来说,无论何时你调用spawn(),它都会返回给你这种子进程对象。在Node中,终止进程的最简单方法是在子进程对象上调用kill()函数。所以在这种情况下,你会调用ls.kill(signal),对于信号,你可以使用'SIGINT', 'SIGTERM',我认为'SIGHUP'也可以。你可以在这里阅读更多关于信号的内容。

然而,你问如果主进程已经终止,如何杀死子进程。为了做到这一点,你必须使用命令行。如果您知道非法子进程的进程id,您可以简单地运行kill <pid>,其中pid是进程id。您可以从子进程对象中获得进程id。如果您不知道pid并且无法获得它,那么您可以运行ps -eaf,它将打印出计算机上当前正在运行的所有进程的列表,这是一个很大的列表。因此,为了帮助找到您所寻找的过程,您可以执行ps -eaf | grep <process-name>,这可能会帮助您找到该过程。例如,如果在本例中ls命令没有死亡,这实际上是不可能发生的,我可以执行ps -eaf | grep ls,这很可能会找到正确的进程和进程id。然后可以运行kill <pid>

最新更新