2013-05-02 3 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() служит только для завершения процесса, который по самой своей природе позволяет ОС очищать все буферы.

Вы не можете сделать это из узла, поскольку это не является владельцем выходного буфера.

Это раздражает, но до тех пор, пока у вас есть контроль над сценарием, вы можете его изменить, возможно, разрешить ему использовать параметр командной строки для установки автозапуска?

Надеюсь, это поможет.

+1

Не могли бы вы рассказать о том, как мы это делаем? –

+0

Типичный метод заключается в том, чтобы позволить NUL-байту быть сигналом для сброса. Поэтому всякий раз, когда ваша программа на C читает \ 0, вызовите fflush. – unhammer