2012-11-06 15 views
5

Niedawno podjąłem nauki rur dla zabawy. Utknąłem na kilku częściach, ale mam go w większości zorientowany, myślę, jednak nie mogę wymyślić, jak uzyskać dane wejściowe do przekazania do programu i wyjścia z tego programu w tym samym czasie.Równoczesne wejście i wyjście w Perlu

Obecnie mam ten skrypt Perl, który obsługuje rurociągi:

#!/usr/bin/perl 
use strict; 
use warnings; 
use threads; 
use FileHandle; 
use IPC::Open2; 

my $cv_program = "./test"; #test is the compiled C program below 
my $cv_message = ""; 
my $cv_currentkey = ""; 
my $pid = open2(*PIN, *POUT, $cv_program); 
my $thread_pipeout = threads->create('PIPEOUT', \&PIN); 

$thread_pipeout->detach(); 

while($cv_currentkey ne "\n") 
{ 
    $cv_currentkey = getc(STDIN); 
    $cv_message .= $cv_currentkey; 
} 
print POUT $cv_message; 

sub PIPEOUT 
{ 
    my $PIN = shift; 
    while(<PIN>) 
    { 
     print $_; 
    } 
} 

A potem mam ten program w C, który właśnie wyprowadza coś pyta na sznurku, a następnie drukuje ten ciąg:

#include <stdio.h> 

int main(int argc, char const *argv[]) 
{ 
    char input[100] = {0}; 

    printf("This is a test.\n"); 
    fgets(input, 100, stdin); 
    printf("You entered %s\n", input); 
    return 0; 
} 

wyjście z uruchomieniem skryptu Perl jest:

~/Programming/Perl Pipes$ ./pipe.pl 
Hello 
This is a test. 
You entered Hello 

to zauważyć bloki wh ile bierze dane wejściowe, a następnie drukuje wszystko w bloku po. Potrzebuję go do wydrukowania To jest test, a następnie poczekaj na dane wejściowe, takie jak rzeczywisty program.

Również zauważę, że powodem, dla którego używam getc zamiast STDIN w skrypcie Perla, jest to, że nie mogłem znaleźć sposobu, aby STDIN nie blokował wyjścia z test.c, jednak getc nie działa zbyt dobrze w tym momencie.

Odpowiedz

7

Myślę, że problem występuje głównie na końcu C, a nie na końcu Perla. C widzi, że jego standardowe wyjście trafia do potoku, więc nie jest zbyt skrupulatne, aby upewnić się, że opróżnia swój standardowy bufor wyjściowy przed zapytaniem o standardowe wejście.

Aby rozwiązać ten problem, należy być w stanie po prostu dodać ten wiersz:

fflush(stdout); 

po pierwszym printf a przed fgets.

(Zastrzeżenie: nie testowane.)

+0

Tak prosta odpowiedź i działa. Musiałem jednak dodać fflush po obu instrukcjach printf. Jeśli zostawię go poza ostatnim, wiadomość nigdy nie zostanie wydrukowana. Dzięki za szybką odpowiedź. – ozdrgnaDiies

+0

@ozdrgnaDiies: Nie ma za co! – ruakh

Powiązane problemy