我想创建一个rabbitmq cli像foreverjs一样运行。它可以生成child_process并让它在后台运行,并且可以随时与child_process通信。我面临的问题是当主cli程序退出时,child_process似乎也停止运行,我试图用detached:true和.unref()派生它不起作用。即使父调用程序退出后,我如何在后台运行子进程?
cli.js -父级
const { fork, spawn } = require('child_process');
const options = {
stdio: ['pipe', 'pipe', 'pipe', 'ipc'],
slient:true,
detached:true
};
child = fork('./rabbit.js', [], options)
child.on('message', message => {
console.log('message from child:', message);
child.send('Hi');
// exit parent
process.exit(0);
});
child.unref()
rabbit. js-child如果它已启动并运行,则'i'应保持递增
var i=0;
i++;
if (process.send) {
process.send("Hello"+i);
}
process.on('message', message => {
console.log('message from parent:', message);
});
3条答案
按热度按时间cyvaqqii1#
我认为
fork
没有detached
选项。请参阅fork的节点文档。如果您使用
spawn
,即使父进程退出,子进程也会继续运行。客户名称
兔子.js
我认为当你使用fork时,一个
IPC channel
在父进程和子进程之间建立。你可以尝试在退出父进程之前优雅地断开IPC channel
。我会尝试一下,如果成功的话,我会更新答案。更新日期:
我已经更新了
cli.js
和rabbit.js
,使其可以正常工作。诀窍是在stdio
选项中使用ipc
文件描述符。这样你就可以从子选项与父选项进行通信。如果标记为null
,则前三个fd
将是默认值。要了解更多信息,请参阅stdio选项文档xmd2e60i2#
一个老问题,但对于那些拿起我今天:
fork
确实有一个detached
选项。但是,它也会打开一个IPC通道,如果您想断开父级和子级之间的关系,也必须使用disconnect()
显式关闭该通道。在我的例子中,在确认子进程已经准备好执行其工作之前使用通道是有利的,然后断开它:
这允许我的父进程退出,而不杀死后台进程或通过引用它来保持活动状态。
如果您确实建立了
handle.on(...)
处理程序,那么最好在使用完它们之后将它们与handle.off(...)
断开连接。我使用了一个handle.on('message', (data) => { ... })
处理程序,以允许子处理程序在完成一些异步启动工作后通知父处理程序何时准备好执行其任务。pbgvytdp3#
fork和spawn都有分离选项。
但是,当父进程退出时,子进程可能希望写入初始标准输出(通过“process.stdout.write”、“console.log”等)。但是,此标准输出可能不再可用(因为父进程已终止),从而在子进程中引发一些异常(例如,管道损坏)。这些异常可能导致子进程也意外失败。
如果我们***允许子程序写入某些始终可用的输出***(例如文件),它将不再失败,因为它仍然可以将信息写入有效实体。