如何从 nodejs 刷新子进程

How can I flush a child process from nodejs

我使用 spawn 从 nodejs 调用了一个可执行的 C 程序,但 C 程序似乎不是每次都被刷新。然后,我的节点程序只能在缓冲区已满(4K)或子进程退出时输出子进程的stdout。

为了简化场景,两部分代码应该是:

invoke.js

var spawn = require("child_process").spawn;

var ps = spawn("./echo");
ps.stdout.on("data", (data) => {
    console.log(`${data}`); 
});
process.on("SIGINT", ps.kill);

echo.c

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

static volatile int keep = 1;

void intHandler(int d){
    keep = 0;
}

int main(){
    signal(SIGINT, intHandler);
    int count = 0;
    while(keep) {
            printf("%d hello world!\r\n", ++count);
            sleep(1);
    }
}

如何在 invoke.js 同步中获得 echo 的输出?一件重要的事情是我不能修改 echo.c,我只有二进制

我发现 execa 对此很有用。

您需要阅读有关子进程的文档 processes/forks 以及如何将子进程的输出通过管道传输到父进程: https://nodejs.org/api/child_process.html#child_process_options_stdio

  • 'pipe' - equivalent to ['pipe', 'pipe', 'pipe'] (the default)
  • 'ignore' - equivalent to ['ignore', 'ignore', 'ignore']
  • 'inherit' -equivalent to [process.stdin, process.stdout, process.stderr] or [0,1,2]

在你的情况下,如果你不需要对输出做一些更复杂的事情,你可以去掉 on.data 事件监听器,只用继承选项初始化生成的进程。我修改了 SIGINT 事件绑定,以便更清楚地表明 ps.kill 已被调用。

var spawn = require('child_process').spawn;

var ps = spawn('./echo', { stdio: 'inherit' });

process.on('SIGINT', function (){
  console.log('sigint received');
  ps.kill();
});

https://nodejs.org/dist/latest-v12.x/docs/api/process.html#process_a_note_on_process_i_o

Windows和POSIX有区别。 如果 child_process 在 Windows 上生成,则只有 TTY 类型的标准输出异步工作。 inherit 选项使 child_process 异步,因为 process.stdout 是 TTY 类型。