Ich möchte das effizient machen:
%Vor% Die Aufgabe besteht darin, wc
nur zu starten, wenn eine Eingabe erfolgt. Wenn keine Eingabe erfolgt, sollte das Programm einfach beendet werden.
wc
ist nur ein Beispiel hier. Es wird durch einen viel komplexeren Befehl ersetzt.
Die Eingabe kann aus mehreren TB Daten bestehen, also möchte ich wirklich diese Daten überhaupt nicht berühren (nicht einmal mit sysread
). Ich habe es versucht:
Aber das funktioniert nicht. Gibt es eine andere Möglichkeit, dass ich OUT sagen kann, dass, nachdem es das erste Byte bekommen hat, es gerade von STDIN lesen sollte? Vielleicht einige offene ("& gt; = & amp; 2") Gymnastik kombiniert mit exec
?
Ein untergeordneter Prozess erhält immer Duplikate der Datei-Handles seiner Eltern. Wenn Sie also einfach wc
- entweder mit Backticks oder mit einem Aufruf von system
oder exec
- beginnen, liest er von der gleichen Stelle wie die % Co_de% des Perl-Prozesses.
Wenn Sie STDIN
nur dann starten, wenn etwas zu lesen ist, müssen Sie wc
eingeben , mit dem Sie entweder überprüfen können, ob ein Datei-Handle etwas zu lesen hat oder blockieren, bis etwas hat.
Dieses Programm überprüft, ob IO::Select
Daten wartet, und führt STDIN
aus und druckt seine Ausgabe, falls dies der Fall ist.
Der Parameter für wc
ist ein Timeout in Sekunden. Wenn Sie einen Wert von Null übergeben, wird der Wert sofort zurückgegeben, wobei true zurückgegeben wird (falls tatsächlich Daten vorhanden sind) oder false ( can_read
) .
Wenn Sie keinen Parameter übergeben, wartet undef
auf immer, bis etwas zu lesen ist. Sie können also Ihr Programm anhalten und auf Daten für can_read
warten, indem Sie nur
oder Sie könnten die Konstruktion des Objekts kombinieren, um es noch prägnanter zu gestalten
%Vor% Beachten Sie auch, dass wc
auch mit Dateideskriptoren funktioniert, und da das Fileno für IO::Select
Null ist, könnten Sie
aber das ist nicht sehr beschreibend und würde einen Kommentar benötigen, um Sinn zu ergeben
Die spezifische Lösung, an der Sie interessiert sind, ist unmöglich.
Wie Sie sicherlich schon herausgefunden haben, können Sie nicht feststellen, ob ein Datei-Handle EOF erreicht hat, ohne von ihm gelesen zu haben. [Anscheinend du kannst ] select(2)
wird dich näher bringen. Es wird Ihnen sagen, dass ein Handle EOF erreicht hat oder Daten warten, aber es wird Ihnen nicht sagen, welche. Deshalb suchen Sie nach alternativen Lösungen. Leider ist der, den du gerade betrachtest, genauso unmöglich.
Gibt es eine andere Möglichkeit, dass ich OUT sagen kann, dass es, nachdem es das erste Byte bekommen hat, es einfach von STDIN lesen sollte?
Nein. OUT
ist kein Code; es liest nichts. Es ist eine Variable. Außerdem ist es eine Variable im Elternteil. Das Ändern einer Variablen im übergeordneten Element wirkt sich nicht auf das untergeordnete Element aus.
Vielleicht wollten Sie fragen: Kann man dem Kindprogramm sagen, dass es mit einem zweiten Handle beginnt?
Nein, allgemein gesprochen. Sie können die Variablen eines anderen Programms nicht bearbeiten. Das Programm müsste speziell geschrieben werden, um zwei Dateigriffe zu akzeptieren und nacheinander zu lesen.
Andererseits ist es möglich, einen Dateinamen für ein beliebiges Datei-Handle zu erhalten, also brauchen wir nur ein Programm, das speziell dafür geschrieben ist, zwei Dateinamen zu akzeptieren und nacheinander zu lesen, und das ist ziemlich üblich.
%Vor%(Es sind viele Fehlerüberprüfungen erforderlich.)
Oben wurde cat
als Beispiel für die Verwendung Ihres Programms verwendet, stellt aber eine andere Lösung dar: Warum nicht einfach cat
verwenden? Der Overhead von cat
sollte für ein E / A-gebundenes Programm ziemlich gering sein.