简体   繁体   中英

parent process kills child process, even though detached is set to true

I am really confused by this and have been struggling to find a solution for months. I am on OSX.

I hear that using child_process.spawn with the detached option set to true, will start the child process as a leader of a new process group and if the parent exits, the child process may continue running. However, I never witnessed any evidence of this.

https://nodejs.org/api/child_process.html

For example:

const n = cp.spawn('node', ['watch-transpile.js'], {
    detached: true,
    stdio: ['ignore']
});

the above is executed by the parent, and if we run $ ps aux | grep node $ ps aux | grep node

we get:

Olegzandr        2546   0.0  0.2  3048544  19564   ??  Ss   11:29PM   0:00.09 node lib/transpile/watch-transpile.js

Olegzandr        2541   0.0  0.7  3115684  60216 s000  S+   11:29PM   0:01.47 node index -t -a -w

But when I kill the parent with control-c, the child process dies as well as the parent.

How can I truly create a background process that is independent of the parent process with node? this is killing me!

Try including the child.unref() method.

By default, the parent will wait for the detached child to exit. To prevent the parent from waiting for a given child, use the child.unref() method. Doing so will cause the parent's event loop to not include the child in its reference count, allowing the parent to exit independently of the child, unless there is an established IPC channel between the child and parent.

When using the detached option to start a long-running process, the process will not stay running in the background after the parent exits unless it is provided with a stdio configuration that is not connected to the parent. If the parent's stdio is inherited, the child will remain attached to the controlling terminal.

Example of a long-running process, by detaching and also ignoring its parent stdio file descriptors, in order to ignore the parent's termination:

Example:

const n = cp.spawn('node', ['watch-transpile.js'], {
    detached: true,
    stdio: ['ignore']
}).unref();

Examples ( from the documentation ):

const spawn = require('child_process').spawn;

const child = spawn(process.argv[0], ['child_program.js'], {
  detached: true,
  stdio: ['ignore']
});

child.unref();

Alternatively one can redirect the child process' output into files:

const fs = require('fs');
const spawn = require('child_process').spawn;
const out = fs.openSync('./out.log', 'a');
const err = fs.openSync('./out.log', 'a');

const child = spawn('prg', [], {
 detached: true,
 stdio: [ 'ignore', out, err ]
});

child.unref();

Aha! Of course. Those stupid Node docs!

This works.

        const n = cp.spawn('node', ['lib/transpile/watch-transpile.js'], {
            detached: true,
            stdio: ['ignore', 'ignore', 'ignore']
        });

You explicitly ignore each stdio stream, not just using 'ignore' once; the docs don't mention this directly, but it makes sense given that the stdio property is an array.

See this issue on Github: https://github.com/nodejs/node/issues/7269#issuecomment-225698625

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM