Ho uno script Perl che utilizza uno strumento esterno (cleartool) per raccogliere informazioni su un elenco di file. Voglio usare IPC per evitare generando un nuovo processo per ogni file:Come faccio a leggere un IPC non bloccante su Windows?
use IPC::Open2;
my ($cin, $cout);
my $child = open2($cout, $cin, 'cleartool');
comandi che ritornano singole linee funzionano bene. per esempio.
print $cin "describe -short $file\n";
my $description = <$cout>;
comandi che ritornano più righe mi hanno in un vicolo cieco per il modo di consumare l'intera risposta senza essere appeso da un blocco di leggere:
print $cin "lshistory $file\n";
# read and process $cout...
Ho cercato di impostare il filehandle per non bloccante si legge tramite fcntl
:
use Fcntl;
my $flags = '';
fcntl($cout, F_GETFL, $flags);
$flags |= O_NONBLOCK;
fcntl($cout, F_SETFL, $flags);
ma Fcntl muore con il messaggio "il venditore non ha definito Fcntl macro F_GETFL."
Ho provato a utilizzare IO :: Handle per impostare $cout->blocking(0)
ma non riesce (restituisce undef
e imposta $!
su "Errore sconosciuto").
Ho cercato di usare select
per determinare se ci sono dati disponibili prima di tentare di leggere:
my $rfd = '';
vec($rfd, fileno($cout), 1) = 1;
while (select($rfd, undef, undef, 0) >= 0) {
my $n = read($cout, $buffer, 1024);
print "Read $n bytes\n";
# do something with $buffer...
}
ma che pende senza mai aver letto nulla. Qualcuno sa come farlo funzionare (su Windows)?
Cosa pensi di fare mentre non blocchi su IO? – jrockway
Voglio leggere fino a quando non interrompo i dati, che sembrerebbero più affidabili del tentativo di determinare che ho raggiunto la fine analizzando i dati che ho già recuperato. (Non c'è nessuna indicazione "questa è l'ultima riga" nei dati.) –
Cercando in giro per un problema correlato, ho trovato questo commit su GitHub, che sembra invocare la magia nera per creare un socket non bloccante: https: // github .com/kthakore/frozen-bubble/commit/735dd2307455e32c69827e013992c2d222cb7347 –