为什么 nodejs spawn process 变成 <defunct> 直到 parent 退出
Why nodejs spawn process become <defunct> until parent exited
先来看现象,
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代码,没有显示,好像没有触发事件。
然后运行"ps -ef | grep ls | grpe -v grep"在另一个shell,结果是:
liyuanq+ 10995 10990 0 11:06 pts/3 00:00:00 [ls] <defunct>
如果删除代码:
while(true){}
节点进程退出,并触发on data事件。
问题是为什么节点在父节点进程退出之前实际完成其工作时不关闭派生进程。
我的环境:
OS: Debian 8.4 x86_64
节点:v6.1.0
非常有趣的观察,谢谢!
如果有专门的线程在child上执行wait(),这种情况就不会发生
如果子退出和父执行 wait() 之间存在间隙,则子将在该间隙内被视为已失效。
在节点中,因为我们只有一个线程,而且它正在执行你的无限循环,所以它无法进入事件循环,拦截子出口并从任务列表中清除子 ID。
如果您将 while-true 循环替换为具有较长延迟的 setTimeout,线程将获得空闲 CPU,等待子进程并将其从任务列表中清除 - 我已经验证了这一点。
希望对您有所帮助。
先来看现象,
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代码,没有显示,好像没有触发事件。
然后运行"ps -ef | grep ls | grpe -v grep"在另一个shell,结果是:
liyuanq+ 10995 10990 0 11:06 pts/3 00:00:00 [ls] <defunct>
如果删除代码:
while(true){}
节点进程退出,并触发on data事件。
问题是为什么节点在父节点进程退出之前实际完成其工作时不关闭派生进程。
我的环境:
OS: Debian 8.4 x86_64
节点:v6.1.0
非常有趣的观察,谢谢!
如果有专门的线程在child上执行wait(),这种情况就不会发生
如果子退出和父执行 wait() 之间存在间隙,则子将在该间隙内被视为已失效。
在节点中,因为我们只有一个线程,而且它正在执行你的无限循环,所以它无法进入事件循环,拦截子出口并从任务列表中清除子 ID。
如果您将 while-true 循环替换为具有较长延迟的 setTimeout,线程将获得空闲 CPU,等待子进程并将其从任务列表中清除 - 我已经验证了这一点。
希望对您有所帮助。