【问题标题】:How to keep forked child process alive in node js如何在节点 js 中保持分叉的子进程处于活动状态
【发布时间】:2019-01-27 10:32:42
【问题描述】:

我想创建一个rabbitmq cli,像foreverjs 一样使用node.js 运行。它可以生成 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 - 孩子 如果它启动并运行,'i' 应该保持递增

var i=0;
i++;
if (process.send) {
  process.send("Hello"+i);
}

process.on('message', message => {
  console.log('message from parent:', message);
});

【问题讨论】:

    标签: javascript node.js rabbitmq forever


    【解决方案1】:

    我认为fork 没有detached 选项。参考node docs for fork

    如果您使用spawn,即使父级退出,子级也会继续运行。我已经修改了你的代码以使用spawn

    cli.js

    const { fork, spawn } = require('child_process');
    const options = {
      slient:true,
      detached:true,
        stdio: [null, null, null, 'ipc']
    };
    
    child = spawn('node', ['rabbit.js'], options);
    child.on('message', (data) => {
        console.log(data);
        child.unref();
        process.exit(0);
    });
    

    rabbit.js

    var i=0;
    i++;
    process.send(i);
    // this can be a http server or a connection to rabbitmq queue. Using setInterval for simplicity
    setInterval(() => {
        console.log('yash');
    }, 1000);
    

    我认为当你使用 fork 时,父进程和子进程之间会建立一个IPC channel。您可以尝试在退出父进程之前优雅地断开IPC channel。如果可行,我会尝试并更新答案。

    更新:

    我已更新 cli.jsrabbit.js 以使其按要求工作。诀窍是在stdio 选项中使用ipc 文件描述符。这样您就可以从孩子与父母沟通。如果标记为null,前三个fds 将是默认值。更多信息,请参考stdio options docs

    【讨论】:

    • 如果可行,我还能通过消息回调与子进程通信吗?
    • 我不这么认为。特定于fork 的通信。您可能必须找到另一种与子进程通信的方法。如果它将子的 stdio 重定向到父级,则可以使用 spawn 完成。但我想IPC 类的消息传递无法完成。
    • 在那种情况下,pm2 或永远如何实现这样的功能。就像永远开始然后进程被带到后面并且可以通过某种进程ID停止对应?
    • 这可以通过 spawn 来完成,对吧?用 spawn 启动一个子进程,然后杀死父进程。孩子还继续跑? forever 可能会将stdiostderr 通过管道传输到父进程,这可以通过spawn 实现。
    • 是否可以给我写一个小代码片段,显示在 nodejs 中使用哪种方法来实现这一点?对不起,我很痛苦
    猜你喜欢
    • 2011-08-23
    • 2016-03-15
    • 2020-08-16
    • 1970-01-01
    • 1970-01-01
    • 2021-09-16
    • 2011-04-04
    • 2022-06-28
    • 1970-01-01
    相关资源
    最近更新 更多