为什么nodejs spawn进程在父节点退出之前变为<defunct>

时间:2016-06-15 03:36:47

标签: node.js spawn zombie-process defunct

让我们先看看这个现象,

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

1 个答案:

答案 0 :(得分:3)

非常有趣的观察,谢谢!

如果有一个专用线程对子进行wait(),则不会发生这种情况

如果子出口之间存在间隙而父母执行wait(),则该孩子将被视为在该间隙内不存在。

在节点中,因为我们只有一个线程,并且它正在执行无限循环,所以它无法进入事件循环,拦截子出口并从任务列表中清除子ID。

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

希望这有帮助。