4

先来看现象,

节点代码:

const cp = require('child_process');

var ls = cp.spawn('ls', ['/']);

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

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

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

while(true){}

运行这个 nodejs 代码,没有任何显示,似乎没有触发任何事件。

然后在另一个shell中运行“ps -ef | grep ls | grpe -v grep”,结果是:

liyuanq+ 10995 10990  0 11:06 pts/3    00:00:00 [ls] <defunct>

如果删除代码:

while(true){}

节点进程退出,并触发 on data 事件。

问题是为什么节点在父节点进程退出之前实际完成它的工作时不关闭生成的进程。

我的环境:

操作系统:Debian 8.4 x86_64

节点:v6.1.0

4

1 回答 1

4

非常有趣的观察,谢谢!

如果有专门的线程对child执行wait(),就不会出现这种情况

如果子退出和父执行 wait() 之间存在间隙,则在该间隙内子将被视为已失效。

在node中,由于我们只有一个线程,并且它正在执行你的无限循环,它无法进入事件循环,拦截子退出并从任务列表中清除子ID。

如果您用延迟较长的 setTimeout 替换您的 while-true 循环,则线程会获得空闲 CPU,等待子进程并将其从任务列表中清除 - 我已经验证了这一点。

希望这可以帮助。

于 2016-06-15T06:07:59.437 回答