让我们先看看这个现象,
Nodejs代码:
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数据事件。
问题是,为什么节点在实际完成它的作业之前不会关闭生成的进程,直到父节点进程退出。
我的环境:
操作系统:Debian 8.4 x86_64
节点:v6.1.0
答案 0 :(得分:3)
非常有趣的观察,谢谢!
如果有一个专用线程对子进行wait(),则不会发生这种情况
如果子出口之间存在间隙而父母执行wait(),则该孩子将被视为在该间隙内不存在。
在节点中,因为我们只有一个线程,并且它正在执行无限循环,所以它无法进入事件循环,拦截子出口并从任务列表中清除子ID。
如果用长时间延迟的setTimeout替换while-true循环,则线程获得空闲CPU,等待子进程并从任务列表中清除它 - 我已经验证了。
希望这有帮助。