即使已将分离设置为true,父进程也会终止子进程

时间:2016-05-25 03:35:43

标签: node.js macos process

我对此感到很困惑,几个月来一直在努力寻找解决方案。我在OSX上。

我听说使用child_process.spawn并将detached选项设置为true,将启动子进程作为新进程组的领导者,如果父进程退出,子进程可能会继续运行。但是,我从未目睹过这方面的任何证据。

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

例如:

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

上述内容由父级执行,如果我们运行$ ps aux | grep node

我们得到:

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

但是当我用control-c杀死父级时,子进程和父进程一样死掉。

如何真正创建一个独立于具有节点的父进程的后台进程?这是杀了我!

2 个答案:

答案 0 :(得分:2)

尝试使用child.unref()方法。

  

默认情况下,父级将等待已分离的子级退出。至   防止父母等待给定的孩子,使用    child.unref()方法。这样做会导致父事件循环   不包括孩子的参考计数,允许父母   除非已建立IPC,否则独立于儿童退出   孩子和父母之间的渠道。

     

使用分离选项启动长时间运行的进程时,   父进程退出后,进程将不会在后台运行   除非它提供了未连接的stdio配置   到了父母。如果父母的stdio被继承,孩子将会继承   保持与控制终端的连接。

     

长时间运行的过程示例,通过分离并忽略它   父stdio文件描述符,以忽略父母的   终止:

示例:

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

示例来自文档):

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

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

child.unref();

或者,可以重定向子进程'输出到文件:

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();

答案 1 :(得分:2)

啊哈!当然。那些愚蠢的Node文档!

这很有效。

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

您明确忽略了每个stdio流,而不仅仅是使用' ignore'一旦;文档没有直接提到这一点,但鉴于stdio属性是一个数组,它是有道理的。

在Github上查看此问题:https://github.com/nodejs/node/issues/7269#issuecomment-225698625