node.jsspawnzombie-processdefunct

Why nodejs spawn process become <defunct> until parent exited


Let's see the phenomenon first,

Nodejs code:

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){}

Run this nodejs code, nothing displayed, seems no event been triggered.

Then run "ps -ef | grep ls | grpe -v grep" in another shell, result is:

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

If remove the code:

while(true){}

the node process exit, and triggered the on data event.

The problem is why node not close the spawned process when it actually finished it's job until the parent node process exited.

My environment:

OS: Debian 8.4 x86_64

Node: v6.1.0


Solution

  • Very interesting observation, thank you!

    If there is a dedicated thread that performs wait() on the child, this scenario will not happen

    If there is a gap between the child exits and the parent performs wait(), the child will be seen as defunct within that gap.

    In node, as we have only a single thread, and it is performing your infinite loop, there is no way it can enter the event loop, intercept the child exit and clear the child’s ID from the task list.

    If you replace your while-true loop with a setTimeout with long delay, the thread gets free CPU, waits for the child and clears it from the task list - I have verified that.

    Hope this helps.