2013-05-02 51 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