2013-05-02 37 views
3

我想在node.js上运行一个脚本,该脚本将数字顺序地发送到可执行文件a.out,该文件对其进行平方并将结果写入其stdout。发生这种情况时,会发送下一个号码。下面的代码:如何手动将管道冲洗到node.js中的子进程?

var spawn = require('child_process').spawn; 
var p = spawn("./a.out",[],{"stdio":"pipe"}); 
p.stdout.setEncoding("utf8"); 
p.stdout.on("data",function(data){ 
    var x = parseInt(data.trim()), y = Math.sqrt(x); 
    console.log("received",x); 
    if(++y===10) p.kill(); 
    else { 
     console.log("sending",y); 
     p.stdin.write(y+"\n"); 
    } 
}); 
var start = 2; 
console.log("sending",start); 
p.stdin.write(start+"\n"); 
setTimeout(function(){ p.stdin.end(); },1000); 

其中a.out是编译版本下面的C程序:

#include<stdio.h> 
int main(){ 
    int x; 
    while(scanf("%d",&x)!=EOF) 
     printf("%d\n",x*x); 
    return 0; 
} 

不过,我得到以下的输出:

sending 2 
received 4 
sending 3 

events.js:72 
    throw er; // Unhandled 'error' event 
     ^
Error: write after end 

改变毫秒值在setTimeout只会延迟错误。显然,我试图发送给a.out的数据正在缓冲,并且在我终止管道时仅发送。我如何手动刷新它?

回答

1

我一直在这一整天工作。

问题是你生成的进程的STDOUT需要刷新它的输出缓冲区,否则它会坐在那里直到它填满,在这种情况下你的代码将不会再执行。

p.stdin.end()仅用于结束进程,它本质上允许OS清除所有缓冲区。

您不能从节点执行此操作,因为它不是输出缓冲区的所有者。

这很烦人,但只要你有脚本的控制权,你可以在那里修改它,也许允许它使用命令行选项来设置自动刷新?

希望这有一些帮助。

+1

请您详细说明我们如何去做这件事? – 2013-08-31 10:08:45

+0

一个典型的方法是让NUL字节成为一个信号来刷新。所以每当你的C程序读取\ 0时,请调用fflush。 – unhammer 2013-09-19 08:33:05