【问题标题】:parent process kills child process, even though detached is set to true父进程杀死子进程,即使 detached 设置为 true
【发布时间】:2016-09-22 11:32:24
【问题描述】:

我对此感到非常困惑,并且几个月来一直在努力寻找解决方案。我在 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 杀死父进程时,子进程和父进程一样死亡。

如何才能真正创建一个独立于带有节点的父进程的后台进程?这可要了我的命!

【问题讨论】:

    标签: node.js macos process


    【解决方案1】:

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

    这行得通。

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

    您明确忽略每个标准输入输出流,而不仅仅是使用一次“忽略”;文档没有直接提到这一点,但考虑到 stdio 属性是一个数组,这是有道理的。

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

    【讨论】:

      【解决方案2】:

      尝试包含child.unref() 方法。

      默认情况下,父母会等待分离的孩子退出。到 防止父母等待给定的孩子,使用 child.unref() 方法。这样做会导致父级的事件循环 不将子项包含在其引用计数中,从而允许父项 独立于孩子退出,除非有已建立的 IPC 孩子和父母之间的通道。

      当使用 detached 选项启动一个长时间运行的进程时, 父进程退出后进程不会在后台继续运行 除非它提供了未连接的 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();
      

      【讨论】:

      • 刚刚添加了一个答案,它有效。 child.unref() 解决了手头问题的反面。我需要防止孩子在父母退出时退出。 child.unref() 允许父母退出,即使孩子没有。完美的逆:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-14
      • 2014-03-19
      • 2011-09-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多