节点子进程:它总是会自行终止吗?
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 控制台消息,并在完成任务后自动退出。
我的问题是:
什么情况下会去'error'事件?
有没有可能子进程无法终止?如果是这样,什么时候会发生?
如果情况 2 发生,当我的主进程已经终止时,如何杀死这些子进程?
只要ls
命令,子进程就会出错,或者进程出错。因此,如果 /user
不存在,则进程会出错,然后终止。当你在 Node 中生成一个子进程时,它的行为就像你在命令行中执行命令一样。大多数进程都会死于错误。这真的取决于。您必须阅读 linux 或 unix 或任何您正在使用的 OS 的文档,以了解发生错误时会发生什么。但是这些系统级命令应该死掉 对于像 ls
这样的简单命令,它是非常安全的。如果它出错,它就会死亡。结束.
子进程可能没有终止。很难准确地说出子进程何时不会终止。各种各样的事情都可能导致这种情况。例如,您 fork 了某个进程但从未关闭它,或者子进程由于某种原因陷入了某种无限循环。有些进程虽然已启动并且打算无限期地继续,但只能手动关闭。
如果情况 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>
.
希望对您有所帮助。
我有像这样生成子进程的代码:
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 控制台消息,并在完成任务后自动退出。
我的问题是:
什么情况下会去'error'事件?
有没有可能子进程无法终止?如果是这样,什么时候会发生?
如果情况 2 发生,当我的主进程已经终止时,如何杀死这些子进程?
只要
ls
命令,子进程就会出错,或者进程出错。因此,如果/user
不存在,则进程会出错,然后终止。当你在 Node 中生成一个子进程时,它的行为就像你在命令行中执行命令一样。大多数进程都会死于错误。这真的取决于。您必须阅读 linux 或 unix 或任何您正在使用的 OS 的文档,以了解发生错误时会发生什么。但是这些系统级命令应该死掉 对于像ls
这样的简单命令,它是非常安全的。如果它出错,它就会死亡。结束.子进程可能没有终止。很难准确地说出子进程何时不会终止。各种各样的事情都可能导致这种情况。例如,您 fork 了某个进程但从未关闭它,或者子进程由于某种原因陷入了某种无限循环。有些进程虽然已启动并且打算无限期地继续,但只能手动关闭。
如果情况 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>
.
希望对您有所帮助。