Considérez le script suivant:
use IO::File; $| = 1; my ($handle, $pid) = myPipe(); if ($pid == 0) { print "$$"; sleep 5; exit; } print "child: ".<$handle>."\n"; sub myPipe { my $handle = new IO::File(); my $pid = open($handle, "-|"); return ($handle, $pid); }
3 Réponses :
Rincer le tuyau ne se produit pas sur un calendrier fixe. Les deux seules façons que vous pouvez forcer le tuyau à rincer est en sortant du processus d'enfant (ce que vous faites maintenant) ou en appelant explicitement flush code>. Vous pouvez faire chasser votre poignée à Perl en effectuant l'une des opérations suivantes: p>
\ n code> à la fin du message de l'enfant, qui fera (généralement) le tuyau chasse contre li>
$ | code> à 1, ce qui provoque la touche de fichier actuellement sélectionnée de manière automatique li>
io :: poignée code> et appelant
$ gérer-> flush code>. li>.
io :: gérer code> et réglage
$ gérer-> autoflush = 1 code> li> li>
ul>
Rincer le tuyau n'est pas géré par le noyau. Le tampon est une fonction Userland!
sur certains systèmes (la plupart?), les tuyaux utilisent des E / S Buffering par défaut. Mettre une instruction dans votre fonction mais même lorsque la mise en mémoire tampon est éteinte, Perl ne rincent toujours pas après un nouvelle ligne. Donc, vous pouvez également vouloir que votre enfant inclure une nouvelle ligne dans la sortie. P> p> mypipe code> fonction. P>
Ce n'est pas tout à fait juste. Une poignée est non tamponnée (affleurante après chaque impression) si une autoflush est allumée, tamponnée à la ligne (affleurante après chaque transversale) si une autoflush est éteinte et que la poignée est ouverte sur une TTY et une touche bloquée (rinquisser lorsqu'un tampon , généralement de quelques ko, est plein) sinon.
Re: Mettre à jour - voir la réponse de Sean. La nouvelle ligne ne compte pas à cause de la mise en mémoire tampon, mais parce que le mode LIVELINE / <> code> dans le parent doit lire une nouvelle ligne avant de rentrer i> - sauf à EOF :)
@Hobbs - Merci d'avoir clarifié. Dans cet exemple particulier, l'appel à <$ gérer> code> dans le parent ne revient pas tant qu'il n'y a pas de nouvelle ligne dans l'entrée ou que l'entrée est fermée. Donc, la nouvelle ligne est toujours la question, mais pour une raison légèrement différente de celle que je pensais. Vous pouvez faire quelque chose de funky avec
$ / code>, je suppose.
Il y a deux problèmes. Premièrement, le processus de l'enfant tamponne sa production; et deuxièmement, le processus parent utilise l'opérateur Donc, une façon d'obtenir le résultat que vous étiez S'attendre à ce que le processus d'enfant aime fermer son flux de sortie immédiatement après l'écriture: p> Un autre moyen est d'ajouter une nouvelle ligne à la sortie du processus enfant, puis de rincer le flux: p> Le rinçage est nécessaire car les tuyaux sont (généralement) ignorés, plutôt que des flux tamponnés sous forme de lignes lorsque des flux connectés au terminal sont généralement. P> une troisième alternative est Pour définir le flux de sortie du processus enfant sur AUTOFLUSH: P> code>, qui bloque jusqu'à la disponibilité d'une ligne complète ou jusqu'à la fin de fichier.
if ($pid == 0) {
$| = 1;
print "$$\n";
sleep 5;
exit;
}
Merci pour la réponse approfondie. J'ai réalisé plus tard que l'utilisation de <> aurait besoin d'un nouveau caractère de ligne.