简体   繁体   English

守护被'fork'的'child_process'

[英]Daemonize 'child_process' that was 'fork'ed

I am trying to achieve a behavior similar to one that httpd has when starting with NodeJS. 我正在尝试实现与从NodeJS开始时httpd相似的行为。 When we say: 当我们说:

service httpd start

In ps , we'll see: 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

Notice how httpd master and child have no terminal ( ? is shown instead of pts/0 for grep ). 注意httpd master和child没有终端( grep显示为?而不是pts/0 )。

Now... I need an IPC channel and therefore I use child_process.fork but no matter what I do, every time I see a terminal still attached to my daemon. 现在...我需要一个IPC通道,因此我使用child_process.fork,但是无论我做什么,每次我看到仍然连接到守护程序的终端时。 Here is the code you are welcome to experiment on: 这是欢迎您尝试的代码:

c.js - controller c.js控制器

var cp = require('child_process');

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

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

d.js - daemon d.js守护程序

process.send('ready');

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

And this is what I see in terminal: 这就是我在终端中看到的:

[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 still has my pts/0 and writes test to it even when it's already interactive with bash for me. d.js仍然有我的pts/0 ,即使它已经与bash交互,我也会对其进行test

How do I fix that and make daemon drop the terminal? 如何解决该问题并使守护程序删除终端? I don't care which side ( c.js or d.js ) gets adjustments to code, I control both, but I need that IPC channel and therefore this has to be done via fork . 我不在乎哪一侧( c.jsd.js )都可以对代码进行调整,我可以同时控制两者,但是我需要该IPC通道 ,因此必须通过fork来完成。

This can be solved by ditching fork in favor of spawn . 这可以通过放弃forkspawn卵来解决。 Same code can then be rewritten to: 然后可以将相同的代码重写为:

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

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

The stdio part is how fork works internally. stdio部分是fork内部的工作方式。 I have no idea why they decided to not expose the full array and instead gave only silent . 我不知道为什么他们决定不公开整个数组,而只给出了silent

d.js will then have no terminal right at the start (it will be /dev/null - same as httpd ). d.js在开始时将没有终端(它将为/dev/null d.jshttpd相同)。 Not tested on Windows. 未在Windows上测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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