守护进程 'child_process' 被“分叉”

Daemonize 'child_process' that was 'fork'ed

我正在尝试实现一种类似于 httpd 开始使用 NodeJS 时的行为。当我们说:

service httpd start

ps 中,我们将看到:

[root@dev ~]# service httpd start
Starting httpd:                                            [  OK  ]
[root@dev ~]# ps auxf | grep httpd
root      3395  0.0  0.1   6336   304 pts/0    R+   12:03   0:00  |       \_ grep httpd
root      3391  0.0  1.3 175216  3656 ?        Ss   12:02   0:00 /usr/sbin/httpd
apache    3393  0.0  0.9 175216  2432 ?        S    12:02   0:00  \_ /usr/sbin/httpd

注意 httpd master 和 child 如何没有终端(显示 ? 而不是 greppts/0)。

现在...我需要一个 IPC 通道,因此我使用 child_process.fork 但无论我做什么,每次我看到一个终端仍然连接到我的守护程序。欢迎您试验以下代码:

c.js - 控制器

var cp = require('child_process');

var d = cp.fork('d.js', {});

d.on('message', function() {
  d.disconnect();
  d.unref();
});

d.js - 守护进程

process.send('ready');

setTimeout(function() {
  console.log('test');
}, 10000);

这是我在终端中看到的:

[root@dev ~]# node c.js                 # running the control script
[root@dev ~]# ps auxf | grep node       # my terminal is interactive again so I check
root      3472  0.0  0.3 103308   864 pts/0    S+   12:13   0:00  |       \_ grep node
root      3466  1.1  5.6 648548 14904 pts/0    Sl   12:13   0:00 /usr/bin/node d.js
[root@dev ~]# test                      # appears outta nowhere because d.js still has this stdout

d.js 仍然有我的 pts/0 并写入 test 即使它已经与我的 bash 交互。

我该如何解决这个问题并让守护进程删除终端?我不在乎哪一侧(c.jsd.js)得到调整代码,我控制两者,但我需要 IPC 通道 ,因此必须通过 fork.

完成

这可以通过放弃 fork 而改用 spawn 来解决。然后可以将相同的代码重写为:

var cp = require('child_process');
var d = cp.spawn(process.execPath, ['./d.js'], {
  detached: true,
  stdio: ['ignore', 'ignore', 'ignore', 'ipc']
});

d.unref();
d.disconnect();

stdio 部分是 fork 的内部工作方式。我不知道他们为什么决定不公开整个数组,而是只给出 silent.

d.js 将在开始时没有终端(它将是 /dev/null - 与 httpd 相同)。未在 Windows.

上测试