Pygo: Wie funktioniert can_read von IO::Select?

Hallo,

Mich würde mal die genaue Funktionsweise von der Funktion interessieren - bisher konnte ich aber nur finden, wie man das verwendet und was es zurückgibt.

Warum ich es wissen möchte: Ich möchte gerne aus jedem Handle nur genau eine Zeile auslesen pro Schleifendurchgang (also auch pro can_read()-Aufruf). Jetzt kommt es aber vor, dass das Handle nicht als lesbar von der Funktion erkannt wird, wenn gerade nichts 'neues' in das Handle gelangt ist (handelt sich zB um eine pipe), auch wenn noch ein paar Zeilen zu lesen wären.

Ist das ein Problem der Funktion oder muss es irgendwie an mir liegen?

Gruss - Py

  1. 你好 Pygo,

    Hallo,

    Mich würde mal die genaue Funktionsweise von der Funktion interessieren

    IO::Select ist ein Wrapper um den select(2)-Systemcall. Der prüft, bei
    welchen Deskriptoren ein read(2)- bzw. ein write(2)-Call nicht blockieren
    würde.

    Warum ich es wissen möchte: Ich möchte gerne aus jedem Handle nur genau
    eine Zeile auslesen pro Schleifendurchgang (also auch pro can_read()-
    Aufruf). Jetzt kommt es aber vor, dass das Handle nicht als lesbar von
    der Funktion erkannt wird, wenn gerade nichts 'neues' in das Handle
    gelangt ist (handelt sich zB um eine pipe), auch wenn noch ein paar
    Zeilen zu lesen wären.

    Ist das ein Problem der Funktion oder muss es irgendwie an mir liegen?

    can_read() prüft auf Blockierung. Wenn du vorher schon von dem Socket
    gelesen hast, kann es sein, dass alles gelesen wurde, was zu lesen da war
    und die Daten zwischengecached wurden. Das machen z. B. der <>-Operator
    oder die read()-Funktion von Perl gerne (block-buffered reading). Benutze
    sysread(), um das Problem zu vermeiden; das ist ein echter[tm] Wrapper
    um den read(2)-Systemcall und wirklich unbuffered.

    再见,
     克里斯蒂安

    --
    89,7% aller Statistiken sind frei erfunden!
    http://wwwtech.de/
    1. Hallo Christian,

      Vielen Danke für diesen Hinweis. Mit dem sysread() macht er tatsächlich keine Mucken in die Richtung!

      Gibt es jetzt noch einen Trick bezüglich der Anzahl der zu lesenden Zeichen? Die Sachen sind nämlich nicht gleich gross und ich hab keine Idee wie ich vor dem Auslesen herausfinden sollte, wie viele es sind. Bisher hab ich eben <> genutzt. (Zur Not geb ich ne feste Grösse an und splite es danach auf, aber das ist natürlich nicht so schön.)

      Vielen Dank!
      Py

      1. 你好 Pygo,

        Gibt es jetzt noch einen Trick bezüglich der Anzahl der zu lesenden
        Zeichen? Die Sachen sind nämlich nicht gleich gross und ich hab keine
        Idee wie ich vor dem Auslesen herausfinden sollte, wie viele es sind.
        Bisher hab ich eben <> genutzt. (Zur Not geb ich ne feste Grösse an und
        splite es danach auf, aber das ist natürlich nicht so schön.)

        Da wirst du cachen müssen. Das muss der <>-Operator ja auch tun, exakt aus
        diesem Grund: er weiss nicht, wie lang die Zeile ist. Entweder, du baust
        dir also deinen eigenen Readline-Algorithmus oder du benutzt den <>-Operator
        und versuchst, etwas mit O_NONBLOCK zu basteln (perldoc -f fcntl hält ein
        Beispiel bereit).

        再见,
         克里斯蒂安

        --
        To define recursion, we must first define recursion.
        http://wwwtech.de/
        1. Hallo!

          begin beschämende Frage

          Wie komme ich an perldoc -f fcntl?
          <end beschämende Frage

          Habe bisher nur mal im Internet danach gesucht und nur gefunden, dass ich es mit sysopen benutzen kann - wäre aber für mich obsolet, da ich allein die Pipe mit new IO::Pipe erstelle und nicht mit open.
          Allerdings kann es ja gut sein, dass das nicht die ganze Wahrheit ist - kann mir jemand kurz erklären, wie ich mit dem Hinweis umgehen muss?

          Danke - eine beschämte Py

          1. 你好 Pygo,

            begin beschämende Frage
            Wie komme ich an perldoc -f fcntl?
            <end beschämende Frage

            Über http://perldoc.perl.org/: http://perldoc.perl.org/functions/fcntl.html

            Habe bisher nur mal im Internet danach gesucht und nur gefunden, dass
            ich es mit sysopen benutzen kann

            Nee, du kannst es auf jedes Filehandle und auf jedes IO::Handle-Objekt
            anwenden.

            wäre aber für mich obsolet, da ich allein die Pipe mit new IO::Pipe
            erstelle und nicht mit open.

            Du bekommst die Handles über $pipe->reader() bzw. $pipe->writer().

            再见,
             克里斯蒂安

            --
            Sich erinnern bedeutet, aus einer Erfahrung nicht ausreichend gelernt zu haben.
            http://wwwtech.de/
          2. begin beschämende Frage
            Wie komme ich an perldoc -f fcntl?
            <end beschämende Frage

            Im DOS Fenster oder der shell
            perldoc eingeben

            u.U. einfacher zu lesen, ist die HTML Version
            unter [Perl Verzeichzniss]/html/

            Struppi.

            1. Hallo Struppi,

              Im DOS Fenster oder der shell
              perldoc eingeben

              Ja, habs ja sogar versucht (auch ein blindes Huhn findet mal ein Korn), aber kommt nur

              Can't locate Pod/Perldoc.pm in @INC (@INC ...) at /usr/bin/perldoc line 9.
              BEGIN failed--compilation aborted at /usr/bin/perldoc line 9.
              <<<<<
              Und leider nicht meine Maschine. Und das html-Verzeichnis find ich grad auch nicht, aber ich glaube, die online-Version kann mir schon weiterhelfen.

              Danke auf jeden Fall!
              Py

              1. Ja, habs ja sogar versucht (auch ein blindes Huhn findet mal ein Korn), aber kommt nur

                Can't locate Pod/Perldoc.pm in @INC (@INC ...) at /usr/bin/perldoc line 9.
                BEGIN failed--compilation aborted at /usr/bin/perldoc line 9.
                <<<<<

                seltsame Installation, ich dachte gerade unter *ixen ist perldoc Standard.

                Und leider nicht meine Maschine. Und das html-Verzeichnis find ich grad auch nicht, aber ich glaube, die online-Version kann mir schon weiterhelfen.

                Ist halt wesentlich langsamer.

                Struppi.

                1. Hi Struppi,

                  Can't locate Pod/Perldoc.pm in @INC (@INC ...) at /usr/bin/perldoc line 9.
                  BEGIN failed--compilation aborted at /usr/bin/perldoc line 9.
                  <<<<<

                  seltsame Installation, ich dachte gerade unter *ixen ist perldoc Standard.

                  Naja, irgendwas scheint ja da zu sein, sonst würde er nicht bis in Zeile 9 kommen, oder versteh ich die Meldung falsch? Ist übrigens ein Linux... Und keine Ahnung, wer da mal was gebastelt hat ;)

                  Gruss - Py