coolblue: Socket, system und Prozess in den Hintergrund schicken

0 47

Socket, system und Prozess in den Hintergrund schicken

coolblue
  • perl
  1. 0

    Einen Schritt weiter

    coolblue
    1. 0
      Philipp Hasenfratz
      1. 0
        coolblue
        1. 0
          Philipp Hasenfratz
          1. 0
            coolblue
            1. 0
              Philipp Hasenfratz
              1. 0

                Eine letzte Frage... hoffentlich :-)

                coolblue
                1. 0
                  Philipp Hasenfratz
                  1. 0
                    coolblue
                    1. 0
                      Philipp Hasenfratz
                      1. 0

                        Der wirklich letzte ... :-)

                        coolblue
                        1. 0
                          Philipp Hasenfratz
                  2. 0

                    CHOMP funktioniert nicht... was mache ich falsch?

                    coolblue
                    1. 0
                      Philipp Hasenfratz
                      1. 0
                        coolblue
                2. 0
                  Struppi
                  1. 0
                    coolblue
                    1. 0
                      EisFux
                      1. 0
                        coolblue
                        1. 0
                          Struppi
                          1. 0

                            Absolut klasse !

                            coolblue
                            1. 0
                              Philipp Hasenfratz
                              1. 0
                                coolblue
                              2. 0
                                coolblue
                                1. 0
                                  Philipp Hasenfratz
                                  1. 0
                                    coolblue
                          2. 0
                            Philipp Hasenfratz
                            1. 0

                              Benchmark, "chomp"-Lösungen

                              Philipp Hasenfratz
                              1. 0
                                coolblue
                                1. 0
                                  Philipp Hasenfratz
                                  1. 0
                                    coolblue
                            2. 0
                              Struppi
                      2. 0
                        Philipp Hasenfratz
                        1. 0
                          coolblue
                          1. 0
                            Philipp Hasenfratz
                            1. 0
                              coolblue
                            2. 0

                              Fehler im Forum nachträglich korrigieren

                              EisFux
                              • zu diesem forum
                              1. 0
                                Christian Kruse
                          2. 0
                            EisFux
                        2. 0
                          EisFux
                          1. 0
                            Philipp Hasenfratz
                            1. 0
                              Philipp Hasenfratz
  2. 0
    Philipp Hasenfratz
    1. 0
      coolblue
      1. 1
        Philipp Hasenfratz
        1. 0
          coolblue

Hallo,

weder fork noch exec scheinen mir bei meinem Problem weiter zu helfen, wenn doch, dann habe ich etwas nicht verstanden oder völlig falsch gemacht.

Ich habe einen Server, der über Socket auf eingehende Verbindungen lauscht. Hierfür benutze ich das Perl-Modul IO::Socket::INET. Mein Client sendet "Befehle" oder auch Pfad+Programmname von Prozessen, die nonstop laufen, an den Server. Der Server soll den Befehl oder den Prozess ausführen und danach weiterhin auf den Port lauschen, um gegebenfalls weitere "Befehle" auszuführen. Er soll nicht auf das Ende des Prozesses warten. Das Problem ist nun, dass der Server an der Stelle, an der er den system Befehl ausführt, solange hängt, bis der mit system gestartete Prozess gekillt wird oder sich selbst beendet.

Ich habe schon viele mögliche Varianten ausprobiert und mich über fork im Archiv kundig gemacht, doch keiner meiner Tests war erfolgreich.

while($client = $server->accept()) {
   $command=<$client>;
   ***system Befehl***
}

An der Stelle von ***system Befehl*** habe ich folgende Tests durchgeführt:

system("$command &");
system("$command 1>/dev/null 2>&1 &");
system('$command &');
system('$command 1>/dev/null 2>&1 &');

#------- fork Test -------#

use POSIX;
while($client = $server->accept()) {
   $command=<$client>;
   $pid = fork;
   exit if $pid;
   system("$command &");
}

Diese vorgehensweise funktioniert auch nicht, denn der Serverprozess, ob nun Child oder Parent, wartet trotzdem auf das Ende des Prozesses.

Mein Ziel ist, dass der Prozess, der mit $command ausgeführt wird, im Hintergrund abläuft und der Serverprozess weiterhin auf Verbindungen lauschen kann. Dabei möchte ich nicht, dass der Serverprozess dupliziert wird, denn wenn 100 Prozesse gestartet werden sollen, gibt es doch auch den Serverprozess 100 Mal. Das möchte ich vermeiden. Der Prozess in $command soll losgelöst laufen.
Ausserdem ist der Port dann dauernt von xxx anderen Serverprozessen belegt.

Das Problem scheint sichtlich am Serverprozess zu liegen, denn wenn ich eine ganz normale for Schleife in einem Perl-Script verwende, gibt es keine Probleme.

Hier ein simples Beispiel:

#!/usr/bin/perl

for($ct=0 ; $ct <= 10 ; $ct++) {
   print "$ct";
   system("sar -u 1 100 &");
}

exit;

Die Ausgabe ist wie folgt:

012345678910

Wenn ich dann in die Prozesstabelle schaue, ist der Prozess "sar" dort zu finden. Das Beispiel hing nicht am system Befehl fest. Warum klappt das nicht über den Serverprozess, der den Befehl vom Client erhält?

Gruß,
coolblue

--
never say oops after you submitted a job :-)
  1. Hallo,

    nun bin ich einen Schritt weiter gekommen.

    Das klapp nicht:

    $command="sar -u 1 100";

    while($client = $server-accept()) {
       $command=<$client>;
       system("$command &");
    }

    Das auch nicht:

    $command="sar -u 1 100";

    while($client = $server-accept()) {
       $command=<$client>;
       system('$command &');
    }

    Aber das klappt:

    while($client = $server-accept()) {
       system('sar -u 1 100 &');
    }

    Der Serverprozess läuft sauber weiter und lauscht auf weitere Verbindungen. Aber ich möchte gerne einen Skalar benutzen...

    Gruß,
    coolblue

    --
    never say oops after you submitted a job :-)
    1. Halihallo coolblue

      $command="sar -u 1 100";
      while($client = $server-accept()) {
         $command=<$client>;
         system("$command &");
      }

      Achtung: Deine vorherige Zuweisung an $command wird überschrieben.
      Vielleicht hast du das nicht gesehen.
      Achtung II: <>-Operator gibt auch den Zeilenumbruch aus! - Also:

      $command=chomp(<$client>)
      system("$command &");

      while($client = $server-accept()) {
         $command=<$client>;
         system('$command &');
      }

      Natürlich nicht '$command &' ist auch kein Befehl. Nur bei doppelten
      Quotes wird die Variable durch dessen Inhalt ersetzt. Vorsicht...

      Aber das klappt:
      while($client = $server-accept()) {
         system('sar -u 1 100 &');
      }

      Glaube ich nicht. $server-accept() gibt wohl einen Fehler, es muss
      $server->accept() heissen :-)

      Viele Grüsse

      Philipp

      1. Hiho Phillip,

        sorry, dass war alles kein cut and paste... sondern habs auf die Schnelle mit einigen Fehlern reingehackt. Nochmal:

        $command="sar -u 1 100";
        while($client = $server-accept()) {
           $command=<$client>;
           system("$command &");
        }

        Achtung: Deine vorherige Zuweisung an $command wird überschrieben.
        Vielleicht hast du das nicht gesehen.
        Achtung II: <>-Operator gibt auch den Zeilenumbruch aus! - Also:

        vom Client wird das Kommando sar -u 1 100 gesendet...

        Warum funktioniert das nicht:

        while($client = $server->accept()) {
           $command=<$client>;
           system("$command &");
        }

        das auch nicht:

        while($client = $server->accept()) {
           system("sar -u 1 100 &");
        }

        und das doch:

        while($client = $server-accept()) {
           system('sar -u 1 100 &');
        }

        Den festen Wert habe ich einfach mal zum Testen reingeschrieben.
        Bei den ersten Beiden Beispielen bleibt das Script am system Befehl hängen, bis sar beendet wurde. Beim letzten nicht :(

        Gruß,
        coolblue

        --
        never say oops after you submitted a job :-)
        1. Halihallo coolblue

          Warum funktioniert das nicht:
          while($client = $server->accept()) {
             $command=<$client>;
             system("$command &");
          }

          Weil $command noch ein Leerzeichen enthält und weil & vielleicht
          nicht so funktioniert, wie du denkst. Ich bin mir nicht sicher, ob
          dies den Prozess detached, ich glaube sogar eher nicht.

          das auch nicht:
          while($client = $server->accept()) {
             system("sar -u 1 100 &");
          }
          und das doch:
          while($client = $server-accept()) {
             system('sar -u 1 100 &');
          }

          Naja, ist doch beides dasselbe, bis auf den -> Operator, den du noch
          immer nicht hast und den doublequotes die hier keinen Einfluss haben.
          Vielleicht funktioniert es nicht, weil du gar keine Requests auf
          deinen Server ausführst...?

          Bei den ersten Beiden Beispielen bleibt das Script am system Befehl hängen, bis sar beendet wurde. Beim letzten nicht :(

          Wie auch immer, lies auch mein zweites Posting:
          https://forum.selfhtml.org/?t=95797&m=581583, das wird ggf. einige Fragen klären.

          Viele Grüsse

          Philipp

          1. Hallo Phillip,

            entschuldige bitte meine Unfähigkeit, die Sache richtig zu schildern.

            Ich starte den Serverprozess folgendermaßen:

            ./slistener.pl

            while($client = $server->accept()) {
               $command=chomp(<$client>);
               print "vor\n";
               system("............");
               print "nach\n";
            }

            Daran erkenne ich, ob etwas angekommen ist oder nicht. "vor" wird ausgegeben, "nach" nicht.

            Und bitte, korrigiere nicht meine Schreib- oder Syntaxfehler, du weißt was ich meine... :-)

            Gruß,
            coolblue

            --
            never say oops after you submitted a job :-)
            1. Halihallo coolblue

              Hallo Phillip,

              Wie war das noch mit den Schreib- und Syntaxfehlern? - Ja, ja, ich
              weiss ja was du meinst, "Philipp" nämlich, richtig? :-)
              So und jetzt lass ich es auch, da du mich so freundlich darum
              gebeten hast :-)

              entschuldige bitte meine Unfähigkeit, die Sache richtig zu schildern.

              Ich glaube ich habe es ja jetzt verstanden ;-)
              Zudem brauche auch ich ein Weekend...

              Ich starte den Serverprozess folgendermaßen:
              while($client = $server->accept()) {
                 $command=chomp(<$client>);
                 print "vor\n";
                 system("............");
                 print "nach\n";
              }

              Daran erkenne ich, ob etwas angekommen ist oder nicht. "vor" wird ausgegeben, "nach" nicht.

              Huh? - Das wäre dann so ein Programm, das immer läuft, nicht? Denn
              system sollte schon irgendwann aufhören...

              Bezüglich anderem Posting:
              Super, dann tut's ja jetzt. Wegen chomp:

              my $command = <$client>;
              $command=chomp($command);

              oder

              my $command = chomp($client->getline());

              Viele Grüsse

              Philipp

              1. Hallo PHILIPP :-)

                my $command = <$client>;
                $command=chomp($command);

                Warum unbedingt chomp? Dieses Beispiel habe ich bisher oft in Foren und Beispielen geselesen, aber geht es denn auch nicht so:

                my $command=<$client>;
                $command=~s/\n//;

                Was wäre daran falsch? Zuviel Code? Zu umständlich - ist ja auch nur eine Zeile mehr (!) ? Oder mehr Rechenzeit - kann unter umständen wichtig sein (!) ?

                Gruß,
                coolblue

                --
                never say oops after you submitted a job :-)
                1. Halihallo coolblue

                  Hallo PHILIPP :-)

                  :-)

                  my $command = <$client>;
                  $command=chomp($command);

                  Warum unbedingt chomp?

                  chomp ist der adäquate Befehl um den Delimiter (im Normalfall die
                  Newline) abzuschneiden. Adäquat deswegen weil Newline nicht umbedingt
                  der Delimiter für die IO-Operationen sein muss.

                  Genausogut könntest du z.B. folgendes tun:

                  use IO::String;    # IO::Socket::INET ist nicht grossartig anders...

                  $/ = ';';   # INPUT_RECORD_SEPERATOR / Delimiter
                  my $s = IO::String->new('1;2;3;4');

                  #                       ^^^^^^^^ das wären dann deine $comment's halt
                  #                       eben mit ; getrennt statt mit Newlines

                  while ( my $rec = $s->getline() ) {    # getline trennt jetzt bei ';'
                      my $rec2 = chomp($rec);
                      print "$rec ist '$rec', wohingegen $rec2 '$rec2' ist.\n";
                  }

                  Was wird bei den $rec2's ausgegeben? - Die ';' sind weg, weil chomp
                  eben auf $/ Rücksicht nimmt. Vielleicht entscheidest du dich
                  irgendwann deinen Server mit $comment's zu füttern, die über ';'
                  getrennt sind und nicht mit Newlines. Dann würde ein s/\n$//
                  jämmerlich versagen, da es eben nicht adäquat für die gewünschte
                  Funktionsweise ist.

                  Dieses Beispiel habe ich bisher oft in Foren und Beispielen geselesen, aber geht es denn auch nicht so:

                  my $command=<$client>;
                  $command=~s/\n//;

                  Solange der INPUT_RECORD_SEPERATOR ($/) die Newline ist, ja.
                  Performanter wäre hier jedoch $command =~ s/\n$//;
                  Da die Position von \n der RegExp-Engine bereits bekanntgegeben wird.

                  Was wäre daran falsch?

                  Bis auf den Umstand dass es performanter geschrieben werden kann und
                  der INPUT_RECORD_SEPERATOR nicht zwingend \n sein muss, nichts.

                  Zuviel Code?

                  Naja, die zwei drei Zeichen mehr...

                  Zu umständlich

                  Nicht adäquat würde ich als Grund angeben.

                  ist ja auch nur eine Zeile mehr (!) ?

                  Hä?

                  Oder mehr Rechenzeit - kann unter umständen wichtig sein (!) ?

                  Puh, das würde nur ein Benchmark beweisen können. Kannst es ja mal
                  testen:

                  perldoc Benchmark

                  Viele Grüsse

                  Philipp

                  1. Hallo,

                    ich nochmal. Nun ja, da ich auch den Client programmiere und darauf acht, immer ein Newline als Separator mitzugeben, kann doch eigentlich nichts schiefgehen.

                    Dein Beispiel 1;2;3;4 könnte ich doch auch mit split auseinanderziehen, oder etwa nicht?

                    Sorry, Perl ist eine neue Welt für mich... lerne auch fleißig :-)

                    Gruß,
                    coolblue

                    --
                    never say oops after you submitted a job :-)
                    1. Halihallo coolblue

                      ich nochmal. Nun ja, da ich auch den Client programmiere und darauf acht, immer ein Newline als Separator mitzugeben, kann doch eigentlich nichts schiefgehen.

                      Ja, natürlich. Mit chomp ist es nur eben wirklich adäquater. Zudem
                      könnte ich mir vorstellen, dass chomp auch schneller ist, aber das
                      liesse sich nur durch einen Benchmark belegen.

                      Dein Beispiel 1;2;3;4 könnte ich doch auch mit split auseinanderziehen, oder etwa nicht?

                      Natürlich ginge es auch mit split. Nur: splitte mal eine 10GB grosse
                      Eingabedatei (hier ist es halt eine Variable, aber mit IO::File
                      kann man das auch mit einer Datei machen), das dauert ein bissle und
                      konsumiert sau viel Speicher.

                      Sorry, Perl ist eine neue Welt für mich... lerne auch fleißig :-)

                      Warum sorry? - Du machst ja alles richtig, immer weiter!

                      Viele Grüsse

                      Philipp

                      1. Ok, du hast Recht!

                        Bevor ich ein Programm beginne, mache ich mir natürlich Gedanken, welche Funktionen das Programm erfüllen soll und wo die Grenzen liegen. Da ich niemals ein 10GB File auseinanderziehen muss, sondern eben immer nur einen Befehl ausführen möchte, reicht das kleine Serverprogramm vollkommen aus.

                        Aber ich werde deinen Rat befolgen und in all meinen Scripts ein Chomp einbauen!

                        _Vielen_ _Dank_ für deinen Rat!

                        Hier noch zwei weitere Threads von mir, bei denen ich mich auf deine Meinung freuen würde!

                        http://forum.de.selfhtml.org/my/?t=95810&m=581630

                        http://forum.de.selfhtml.org/my/?t=95804&m=581603

                        Gruß,
                        coolblue

                        --
                        never say oops after you submitted a job :-)
                        1. Halihallo coolblue

                          Bevor ich ein Programm beginne, mache ich mir natürlich Gedanken, welche Funktionen das Programm erfüllen soll und wo die Grenzen liegen. Da ich niemals ein 10GB File auseinanderziehen muss, sondern eben immer nur einen Befehl ausführen möchte, reicht das kleine Serverprogramm vollkommen aus.

                          Natürlich, oftmals ist es aber so, dass die Anforderungen an ein
                          Programm mit der Zeit ändern, also ist man angehalten möglichst schon
                          am Anfang "gut" (was immer das heissen mag) zu programmieren (es sei
                          denn der Aufwand übersteigt den (späteren) Nutzen nachweisbar).

                          Aber ich werde deinen Rat befolgen und in all meinen Scripts ein Chomp einbauen!
                          _Vielen_ _Dank_ für deinen Rat!

                          Aber gerne.

                          Hier noch zwei weitere Threads von mir, bei denen ich mich auf deine Meinung freuen würde!

                          Keine Sorge, ich lese viel im Forum und wenn ich antworten möchte,
                          dann tue ich es auch ohne Hinweis darauf :-)

                          Viele Grüsse

                          Philipp

                  2. Hallo Philipp,

                    $command="sar -u 1 100\n";
                    $command=chomp($command);
                    print "$command\n";

                    Ausgabe ist: 1

                    ???

                    Viele Grüße,
                    coolblue

                    --

                    never say oops after you submitted a job :-)
                    _der_Ton_macht_die_Musik_!!!_
                    1. Halihallo coolblue

                      $command="sar -u 1 100\n";
                      $command=chomp($command);
                      print "$command\n";
                      Ausgabe ist: 1

                      Ups, mein Fehler. chomp gibt die Anzahl gelöschter Zeichen zurück,
                      nicht der modifizierte String. Wenn du chomp($command) schreibst, hat
                      $command nachher kein abschliessende Newline mehr (ohne erneute
                      Zuweisung zu $command!).

                      Also:
                      $command="sar -u 1 100\n";
                      chomp($command);
                      print "$command\n";

                      Viele Grüsse

                      Philipp

                      1. Hiho,

                        Also:
                        $command="sar -u 1 100\n";
                        chomp($command);
                        print "$command\n";

                        ok, funzt!

                        Viele Grüße,
                        coolblue

                        --

                        never say oops after you submitted a job :-)
                        _der_Ton_macht_die_Musik_!!!_
                2. my $command = <$client>;
                  $command=chomp($command);

                  Warum unbedingt chomp? Dieses Beispiel habe ich bisher oft in Foren und Beispielen geselesen, aber geht es denn auch nicht so:

                  my $command=<$client>;
                  $command=~s/\n//;

                  Welchen sinn soll es machen eine funktion die vorhanden ist und auch mehreren Umständen Funktioniert gegen eine langsamere und schlecht zu wartende Funktion zu ersetzen?

                  Du willst nicht schnell an's Ziel kommen sondern möglichst umständlich?

                  Struppi.

                  1. Hallo Struppi,

                    Welchen sinn soll es machen eine funktion die vorhanden ist und auch mehreren Umständen Funktioniert gegen eine langsamere und schlecht zu wartende Funktion zu ersetzen?

                    1. weiß oder wußte ich nicht was von beidem schneller ist!

                    $command=chomp($command);
                    $command=~s/\n//;

                    1. umständlich ist es auf keinen Fall für die Schreibweise!
                    2. eine schon existierende Funktion ist nicht immer unbedingt schneller, als etwas selbst gestricktes! Beispiel Module: warum sollte ich immer nur vorhandene Perl-Module verwenden, wenn ich mir dabei den ganzen Code (oft) reinhauen muss und ich doch eigentlich viel weniger brauch und es mit einer selbstgestrickten Methode ebensogut hinbekomme?

                    Du willst nicht schnell an's Ziel kommen sondern möglichst umständlich?

                    1. ich stellte die Frage, warum chomp besser ist, weil ich es nicht wußte! Deshalb stellt man doch Fragen oder? Ich habe nicht die Frage gestellt, ob du mich für dumm hälst!

                    Danke für das hilfreiche Kommentar.

                    Gruß,
                    coolblue

                    --
                    never say oops after you submitted a job :-)
                    _der_TON_macht_die_Musik_
                    1. Hallo coolblue,

                      "chomp($command)" entfernt nur den letzten Zeilenumbruch,

                      "$command=~s/\n//" dagegen lässt alle Zeilenumbrüche in $command verschwinden.

                      1. Hallo coolblue,

                        "chomp($command)" entfernt nur den letzten Zeilenumbruch,

                        "$command=~s/\n//" dagegen lässt alle Zeilenumbrüche in $command verschwinden.

                        nun da es in meiner Struktur, in der ich Daten über die Socketverbindung übertrage, nur einen Zeilenumbruch gibt, löst diese Art des entfernens auch mein Problem. Nur hätte ich gerne gewußt, ob diese Art tatsächlich so inperformant ist, wie Struppi behauptete.

                        Gruß,
                        coolblue

                        --
                        never say oops after you submitted a job :-)
                        _der_Ton_macht_die_Musik_!!!_
                        1. nun da es in meiner Struktur, in der ich Daten über die Socketverbindung übertrage, nur einen Zeilenumbruch gibt, löst diese Art des entfernens auch mein Problem. Nur hätte ich gerne gewußt, ob diese Art tatsächlich so inperformant ist, wie Struppi behauptete.

                          Ich bin nicht gut was Benchmarks angeht ( das Modul wurde dir ja schon nahegelegt):

                          use Benchmark;
                          my $text = 'test\n';
                          Benchmark::cmpthese(-1, {
                                  'regExp$' => sub {  $text =~ s/\n$//; },
                                  'regExp' => sub {  $text =~ s/\n//; },
                                  'chomp' => sub {  chomp $text; },
                          });

                          Benchmark: running chomp, regExp, regExp$, each for at least 3 CPU seconds...
                               chomp:  3 wallclock secs ( 3.22 usr +  0.00 sys =  3.22 CPU) @ 19810824.17/
                          s (n=63771043)
                              regExp:  2 wallclock secs ( 3.14 usr +  0.00 sys =  3.14 CPU) @ 8796678.66/s
                           (n=27621571)
                             regExp$:  3 wallclock secs ( 3.06 usr +  0.00 sys =  3.06 CPU) @ 13534063.03/
                          s (n=41441301)
                                        Rate  regExp regExp$   chomp
                          regExp   8796679/s      --    -35%    -56%
                          regExp$ 13534063/s     54%      --    -32%
                          chomp   19810824/s    125%     46%      --

                          aber wie immer, es kann sein das der Benchmark nicht realisitisch ist, da ich nicht mit Mechanismen vertraut bin.

                          Struppi.

                          1. Hallo Struppi,

                            das find ich ja klasse!

                            use Benchmark;
                            my $text = 'test\n';
                            Benchmark::cmpthese(-1, {
                                    'regExp$' => sub {  $text =~ s/\n$//; },
                                    'regExp' => sub {  $text =~ s/\n//; },
                                    'chomp' => sub {  chomp $text; },
                            });

                            Benchmark: running chomp, regExp, regExp$, each for at least 3 CPU seconds...
                                 chomp:  3 wallclock secs ( 3.22 usr +  0.00 sys =  3.22 CPU) @ 19810824.17/
                            s (n=63771043)
                                regExp:  2 wallclock secs ( 3.14 usr +  0.00 sys =  3.14 CPU) @ 8796678.66/s
                            (n=27621571)
                               regExp$:  3 wallclock secs ( 3.06 usr +  0.00 sys =  3.06 CPU) @ 13534063.03/
                            s (n=41441301)
                                          Rate  regExp regExp$   chomp
                            regExp   8796679/s      --    -35%    -56%
                            regExp$ 13534063/s     54%      --    -32%
                            chomp   19810824/s    125%     46%      --

                            Aber widerlegt das nicht deine Theorie, das chomp schneller ist als mein Vorgehen? Aus dem Ergebnis erkenne ich, dass chomp 0.06 CPU-Sekunden mehr benötigt. Ich neige wohl jetzt eher dazu, dass Beispiel von Philipp einzusetzen (s/\n$//).

                            Ich bitte um Antwort.

                            aber wie immer, es kann sein das der Benchmark nicht realisitisch ist, da ich nicht mit Mechanismen vertraut bin.

                            Benchmark ist nicht irgend ein "Tool". Die Tests mit Benchmark sind sehr nahe an der Realität! Ein absolut professionelles Auswertungstool. Wenn "wir" neue Großrechner einkaufen, egal ob bei IBM, Sun oder HP, werden die Maschinen ersteinmal mit einem Großteil unserer eingesetzten Software, zum Beispiel Oracle und selbstentwickelter Jobs, ausführlich mit Benchmark darauf getestet.

                            Selbst zu ext2, ext3, reiser etc. machen wir Tests mit Benchmark.

                            Viele Grüße,
                            coolblue

                            --

                            never say oops after you submitted a job :-)
                            _der_Ton_macht_die_Musik_!!!_
                            1. Halihallo coolblue

                              Benchmark: running chomp, regExp, regExp$, each for at least 3 CPU seconds...
                                   chomp:  3 wallclock secs ( 3.22 usr +  0.00 sys =  3.22 CPU) @ 19810824.17/
                              s (n=63771043)
                                  regExp:  2 wallclock secs ( 3.14 usr +  0.00 sys =  3.14 CPU) @ 8796678.66/s
                              (n=27621571)
                                 regExp$:  3 wallclock secs ( 3.06 usr +  0.00 sys =  3.06 CPU) @ 13534063.03/
                              s (n=41441301)
                                            Rate  regExp regExp$   chomp
                              regExp   8796679/s      --    -35%    -56%
                              regExp$ 13534063/s     54%      --    -32%
                              chomp   19810824/s    125%     46%      --

                              Aber widerlegt das nicht deine Theorie, das chomp schneller ist als mein Vorgehen? Aus dem Ergebnis erkenne ich, dass chomp 0.06 CPU-Sekunden mehr benötigt. Ich neige wohl jetzt eher dazu, dass Beispiel von Philipp einzusetzen (s/\n$//).

                              Achtung, es werden *rund* 3 CPU-Sekunden gemessen. *rund* kann
                              systembedingt eben genau mal 0.06 CPU-Sekunden mehr sein, bzw. im
                              Benchmark von Stuppi sogar 0.22. Aber wichtig ist nicht die
                              verbrauchte Zeit, sondern die Anzahl Iterationen pro Sekunde. Wie
                              du in Stuppis Bench lesen kannst, ist comp mit 20 mio/s eindeutig
                              am schnellsten. Bei meinem Benchmark hat chomp etwa zweimal mehr
                              Strings bearbeiten können, als die beiden RegExp-Lösungen. Meiner
                              Meinung nach ein signifikantes Ergebnis. chomp ist eindeutig der
                              Champion :-)

                              aber wie immer, es kann sein das der Benchmark nicht realisitisch ist, da ich nicht mit Mechanismen vertraut bin.

                              Benchmark ist nicht irgend ein "Tool". Die Tests mit Benchmark sind sehr nahe an der Realität! Ein absolut professionelles Auswertungstool. Wenn "wir" neue Großrechner einkaufen, egal ob bei IBM, Sun oder HP, werden die Maschinen ersteinmal mit einem Großteil unserer eingesetzten Software, zum Beispiel Oracle und selbstentwickelter Jobs, ausführlich mit Benchmark darauf getestet.

                              Nun, Benchmarks sind allgemein keine einfache Sache. Die Ergebnisse
                              sind oft nicht so eindeutig wie man sie gerne hätte. Oftmals spielen
                              bei simpelsten Tests ganz andere Faktoren auch hinein, die eben auch
                              beachtet werden müssen und die Folge ist: selbst einfache Benchmarks
                              können hochkomplex werden bzw. liefern falsche Aussagen. Ich könnte
                              mir vorstellen, dass Stuppi in etwa dies sagen wollte.

                              Viele Grüsse

                              Philipp

                              1. Nun, Benchmarks sind allgemein keine einfache Sache. Die Ergebnisse
                                sind oft nicht so eindeutig wie man sie gerne hätte. Oftmals spielen
                                bei simpelsten Tests ganz andere Faktoren auch hinein, die eben auch
                                beachtet werden müssen und die Folge ist: selbst einfache Benchmarks
                                können hochkomplex werden bzw. liefern falsche Aussagen. Ich könnte
                                mir vorstellen, dass Stuppi in etwa dies sagen wollte.

                                Das sehe ich ein, aber trotzallem muss man sich auf etwas stützen können. Natürlich wird versucht, bei solchen Tests alle möglichen und vor allem alle wissentlichen Faktoren einzukalkulieren.

                                Bei solchen Benchmarks werden für gewöhnlich keine einzelnen Statements geprüft, sondern viel mehr ganze Applikationen und Jobs, die seit eh und jeh eingesetzt werden.

                                Aber trotzdem finde ich die Ausführung von Struppi genial :-)

                                Viele Grüße,
                                coolblue

                                --

                                never say oops after you submitted a job :-)
                                _der_Ton_macht_die_Musik_!!!_
                              2. Hallo Philipp,

                                Achtung, es werden *rund* 3 CPU-Sekunden gemessen. *rund* kann
                                systembedingt eben genau mal 0.06 CPU-Sekunden mehr sein, bzw. im
                                Benchmark von Stuppi sogar 0.22. Aber wichtig ist nicht die
                                verbrauchte Zeit, sondern die Anzahl Iterationen pro Sekunde. Wie
                                du in Stuppis Bench lesen kannst, ist comp mit 20 mio/s eindeutig
                                am schnellsten. Bei meinem Benchmark hat chomp etwa zweimal mehr
                                Strings bearbeiten können, als die beiden RegExp-Lösungen. Meiner
                                Meinung nach ein signifikantes Ergebnis. chomp ist eindeutig der
                                Champion :-)

                                für mein technisches Verständnis... damit ich das nicht falsch verstehe...

                                Der Benchmarktest lief für jedes Statement ca. 3 CPU-Sekunden. Innerhalb dieser Zeit wurde für jedes Statement die Iteration gemessen.

                                Ist das so richtig? Ansonsten versuche es mir verständlich zu erklären, wenn du dir die Zeit dafür nehmen magst.

                                Viele Grüße,
                                coolblue

                                --

                                never say oops after you submitted a job :-)
                                _der_Ton_macht_die_Musik_!!!_
                                1. Halihallo coolblue

                                  für mein technisches Verständnis... damit ich das nicht falsch verstehe...

                                  perldoc Benchmark
                                  oder
                                  http://www.perldoc.com/perl5.8.4/lib/Benchmark.html

                                  Der Benchmarktest lief für jedes Statement ca. 3 CPU-Sekunden. Innerhalb dieser Zeit wurde für jedes Statement die Iteration gemessen.

                                  die Anzahl Iterationen. Eine Iteration ist z.B. genau einmal chomp
                                  auszuführen. Für uns ist nun wichtig zu wissen, wie oft chomp
                                  pro Sekunde ausgeführt werden kann und das ist die
                                  (Anzahl Iterationen)/Sekunde.

                                  Ist das so richtig? Ansonsten versuche es mir verständlich zu erklären, wenn du dir die Zeit dafür nehmen magst.

                                  Ich glaube du hast schon verstanden. Ansonsten rate ich dir
                                  einmal einen Blick in die obengenannte Dokumentation zu werfen, dort
                                  wird alles schön erklärt.

                                  Viele Grüsse

                                  Philipp

                                  1. Hallo Philipp,

                                    Ich glaube du hast schon verstanden.

                                    jupp :-)

                                    Viele Grüße,
                                    coolblue

                                    --

                                    never say oops after you submitted a job :-)
                                    _der_Ton_macht_die_Musik_!!!_
                          2. Halihallo Struppi

                            So, jetzt bin ich auch mal grad am Benchmarken gewesen.

                            use Benchmark;
                            my $text = 'test\n';

                            Hast du dir $text mal ausgeben lassen?

                            my $text = "test\n";

                            sonst gibt's keine abschliessende Newline und du misst zwar etwas,
                            aber bestimmt etwas falsches :-)

                            Benchmark::cmpthese(-1, {
                                    'regExp$' => sub {  $text =~ s/\n$//; },
                                    'regExp' => sub {  $text =~ s/\n//; },
                                    'chomp' => sub {  chomp $text; },
                            });

                            Das Problem ist, dass bei $text nur bei der ersten Iteration die
                            Newline weggehackt wird und alle anderen haben dann nur noch 'test'
                            zu behandeln. Wir messen also wiederum nicht das, was wir wollen.

                            Kleines Update zum Benchmark:

                            use Benchmark;
                            my $text2 = "befehl -cvzf test parameter\n";
                                      ## möglichst Realitätsnahe
                            my $text = $text2;

                            Benchmark::cmpthese(2000000, {
                                    'regExp$' => sub { $text=$text2; $text =~ s/\n$//; },
                                    'regExp' => sub { $text=$text2; $text =~ s/\n//; },
                                    'chomp' => sub { $text=$text2; chomp $text; },
                            });

                            Nunja, das mit den $text=$text2 ist zwar auch nicht das, was wir
                            messen wollen, aber ohne messen wir einfach das falsche. Nun, deshalb
                            habe ich einfach fix 2000000 Iterationen veranschlagt, somit ist
                            $text=$text2 bei allen drei Tests nahezu Konstant und wir messen nur
                            die Unterschiede bei der Newline-wegtrennung. Zudem musste ich diesen
                            Benchmark einige Male nacheinander durchführen um sicher zu gehen,
                            dass die Ergebnisse immer in etwa dieselben bleiben (da $text=$text2
                            viel länger dauert als Newlinewegtrennung können die Ergebnisse durch
                            aus falsch sein, über mehrmaliges Iterieren kann man jedoch bei
                            fast immerwährend gleichen Ergebnissen eine These formulieren).

                            Ach ja, man hätte auch "local $text" sagen können. Aber dort haben wir
                            das Problem, dass local so dermassen langsam ist, dass wir bei allen
                            drei cmp's so ziemlich denselben Durchsatz haben...

                            Nunja, unter'm Strich kann ich sagen: Ich komme auf dieselben
                            Aussagen (und Folgen) wie du :-)

                            chomp ist am schnellsten, dann kommt regExp$ und dann chomp. Beim
                            genauen Hinsehen fällt sogar auf, dass chomp stets fast doppelt so
                            schnell ist wie die beiden RegExpe und die regExp$ nur wenig
                            schneller ist, als regExp. Wenn man jedoch standardmässig sehr viel
                            längere Shell-Befehle absetzen möchte (>2000 Zeichen), dann wird's
                            wohl eine starke Verbesserung von regExp$ bezüglich regExp geben (
                            müsste man alerdings auch wieder prüfen).

                            Rate  regExp regExp$   chomp
                            regExp   8796679/s      --    -35%    -56%
                            regExp$ 13534063/s     54%      --    -32%
                            chomp   19810824/s    125%     46%      --

                            Ich habe in etwa folgendes:

                            Rate  regExp regExp$   chomp
                            regExp  1422475/s      --     -1%    -56%
                            regExp$ 1437815/s      1%      --    -55%
                            chomp   3205128/s    125%    123%      --

                            Danke für deine Benchmark's Stuppi, hat mich grad motiviert selber
                            auszuprobieren.

                            Viele Grüsse

                            Philipp

                            1. Halihallo zusammen

                              Kleines Update zum Benchmark:

                              BTW: Stuppi, du misst sozusagen wie schnell die drei Lösungen den
                              Newline erkennen. IMO auch ein spannendes Ergebnis. chomp erkennt
                              die Newline am schnellsten (wahrscheinlich deshalb, da es nur einen
                              gewissen Endstring mit dem INPUT_RECORD_SEPERATOR vergleichen müss),
                              regExp$ merkt ihn am zweitschnellsten (auch wieder deshalb, da die
                              Position durch $ bereits manifestiert ist) und regExp muss den ganzen
                              String nach der ersten Newline durchsuchen.

                              Man sieht jedoch beim Vergleichen des Benchmarks von Stuppi und mir
                              auch, dass chomp die Newline anscheinend auch schneller Löschen kann
                              (sonst wären die Verhältnisse der Durchsätze der beiden Benchmarks
                              konstanter). Dies lässt mich die These formulieren, dass chomp
                              einfach die Stringlänge anpasst und die Regular Expression-Lösungen
                              (auch wenn der Substring ganz am Ende des Strings ist) zeitaufwendige
                              Stringmanipulationen (String-Replacements) durchführen. Es ist jedoch
                              nur eine These...

                              Brave new benchmark-world :-)

                              BTW: Wenn jemand Lust hat, könnte man nun auch noch ein
                                   =~ s/\n$//o in die Lösungsliste aufnehmen. Hier wird die RegExp
                                   nur einmal kompiliert und sollte demnach nochmals etwas
                                   schneller sein als die anderen beiden RegExp's. Aber chomp wird
                                   wohl stets am schnellsten bleiben.

                              Viele Grüsse

                              Philipp

                              1. Halihallo zusammen

                                Kleines Update zum Benchmark:

                                BTW: Stuppi, du misst sozusagen wie schnell die drei Lösungen den
                                Newline erkennen.

                                Erkennen oder auch tatsächlich wegschneiden?

                                Iteration: wie oft die Newline innerhalb von 3 CPU-Sekunden erkannt wird? und/oder weggeschnitten wird?

                                Viele Grüße,
                                coolblue

                                --

                                never say oops after you submitted a job :-)
                                _der_Ton_macht_die_Musik_!!!_
                                1. Halihallo coolblue

                                  BTW: Stuppi, du misst sozusagen wie schnell die drei Lösungen den
                                  Newline erkennen.
                                  Erkennen oder auch tatsächlich wegschneiden?

                                  Bei Stuppi: erkennen. Da stets die Variable $text verwendet wird, ist
                                  diese bereits beim zweiten Durchlauf ohne abschliessende Newline.
                                  Deswegen gibt es für alle folgenden Durchläufe gar nichts mehr
                                  wegzuschneiden, da es gar keine Newlines mehr wegzuschneiden gibt.
                                  Deswegen nur erkennen.

                                  Iteration: wie oft die Newline innerhalb von 3 CPU-Sekunden erkannt wird? und/oder weggeschnitten wird?

                                  Ja. Stuppi's Benchmark läuft ziemlich genau 3 CPU-Sekunden
                                  (theoretisch sogar ganz genau genau) für jede der drei
                                  Lösungsvorschläge (chomp, regExp, regExp$). Nun zählt der Benchmark
                                  wie oft die einzelnen Methoden innerhalb dieser 3 CPU-Sekunden
                                  durchlaufen werden können. Diese Durchläufe nennt man Iterationen.
                                  Aufgrund der Anzahl an Iterationen und der genauen Zeitmessung kann
                                  berechnet werden, wieviele Iterationen pro Sekunde möglich sind und
                                  das ist genau die Grösse, die wir wissen wollen, denn daran kann man
                                  ablesen welche Lösung nun die bessere ist.

                                  Viele Grüsse

                                  Philipp

                                  1. Hallo Philipp,

                                    das gefällt mir! Genau die richtige Art Langläufer zu Tunen.

                                    Sowas habe ich gebraucht.

                                    Viele Grüße,
                                    coolblue

                                    --

                                    never say oops after you submitted a job :-)
                                    _der_Ton_macht_die_Musik_!!!_
                            2. So, jetzt bin ich auch mal grad am Benchmarken gewesen.

                              use Benchmark;
                              my $text = 'test\n';

                              Hast du dir $text mal ausgeben lassen?

                              my $text = "test\n";

                              sonst gibt's keine abschliessende Newline und du misst zwar etwas,
                              aber bestimmt etwas falsches :-)

                              Jaja, hatt ich auch schon daran gedacht (deshalb meine Aussage mit dem Mechanismus, mir schwante sowas bereits).

                              Das Problem, wie auch schon angedeutet hast, ist (vermutlich) dass die Zuweisung eines neuen Strings natürlich auch Zeit in anspruch nimm und wir das ja nicht messen wollen.

                              Benchmark::cmpthese(-1, {
                                      'regExp$' => sub {  $text =~ s/\n$//; },
                                      'regExp' => sub {  $text =~ s/\n//; },
                                      'chomp' => sub {  chomp $text; },
                              });

                              Das Problem ist, dass bei $text nur bei der ersten Iteration die
                              Newline weggehackt wird und alle anderen haben dann nur noch 'test'
                              zu behandeln. Wir messen also wiederum nicht das, was wir wollen.

                              Kleines Update zum Benchmark:

                              use Benchmark;
                              my $text2 = "befehl -cvzf test parameter\n";
                                        ## möglichst Realitätsnahe
                              my $text = $text2;

                              Benchmark::cmpthese(2000000, {
                                      'regExp$' => sub { $text=$text2; $text =~ s/\n$//; },
                                      'regExp' => sub { $text=$text2; $text =~ s/\n//; },
                                      'chomp' => sub { $text=$text2; chomp $text; },
                              });

                              Nunja, das mit den $text=$text2 ist zwar auch nicht das, was wir
                              messen wollen, aber ohne messen wir einfach das falsche. Nun, deshalb
                              habe ich einfach fix 2000000 Iterationen veranschlagt, somit ist
                              $text=$text2 bei allen drei Tests nahezu Konstant und wir messen nur
                              die Unterschiede bei der Newline-wegtrennung. Zudem musste ich diesen
                              Benchmark einige Male nacheinander durchführen um sicher zu gehen,
                              dass die Ergebnisse immer in etwa dieselben bleiben (da $text=$text2
                              viel länger dauert als Newlinewegtrennung können die Ergebnisse durch
                              aus falsch sein, über mehrmaliges Iterieren kann man jedoch bei
                              fast immerwährend gleichen Ergebnissen eine These formulieren).

                              jaja nicht einfach das Benchmarking. Ich wollte mich auch zuerst davor drücken (war ja auch schon spät) aber letztlich siegte meine persönliche Neugier und auch wenn collblue ein bisschen dogmatisch rüberkommt, scheint er ja nicht total ignorant zu sein. Insofern hoffte ich einerseits auf Verbesserungen von Anderen an meinem Code (was passiert ist) und das ich coolblue zumindest einen Ansatz zeigen konnte mit dem er was anfangen kann (was ja auch passiert ist).

                              Es hat sich also für alle gelohnt ;-)

                              Danke für deine Benchmark's Stuppi, hat mich grad motiviert selber
                              auszuprobieren.

                              gern geschehen :-)

                              Struppi.

                      2. Halihallo EisFux

                        "chomp($command)" entfernt nur den letzten Zeilenumbruch,
                        "$command=~s/\n//" dagegen lässt alle Zeilenumbrüche in $command verschwinden.

                        Nö, das wäre $command =~ s/\n//g;
                        =~ s/\n//; entfernt nur einen Zeilenumbruch und das ist - wie
                        coolblue - richtig feststellt genau der Letzte.

                        Aber wie ich bereits sagte, =~ s/\n$//; ist noch performanter, da der
                        Zeilenumbruch nicht erst gefunden werden muss, sondern nur das letzte
                        Zeichen mit \n verglichen werden muss und falls es denn gleich ist,
                        wird es "weg-replaced".

                        Viele Grüsse

                        Philipp

                        1. Hallo Philipp,

                          Nö, das wäre $command =~ s/\n//g;

                          das ist echt fieß von dir! Ich dachte schon daran, ihn darauf aufmerksam zu machen, weil es mir auch aufgefallen war, habe aber den Mund gehalten, weil ich kürzlich dich noch darum bat, sowas nicht zu tun...

                          tz tz tz :-)

                          Gruß,
                          coolblue

                          --
                          never say oops after you submitted a job :-)
                          _der_Ton_macht_die_Musik_!!!_
                          1. Halihallo und guten Morgen coolblue

                            Nö, das wäre $command =~ s/\n//g;
                            das ist echt fieß von dir! Ich dachte schon daran, ihn darauf aufmerksam zu machen, weil es mir auch aufgefallen war, habe aber den Mund gehalten, weil ich kürzlich dich noch darum bat, sowas nicht zu tun...

                            Och, wer ein klein wenig konstruktive Kritik nicht verträgt, sollte
                            besser zu Hause im Bett bleiben :-)   (das sage ich jetzt weder zu
                            dir, noch zu EisFux)

                            Mal im Ernst, diese kleinen Fehler werden ins Archiv verschoben und
                            ggf. von Suchenden gefunden. Sie lesen, dass s/\n//; alle Zeilenumbrüche
                            löscht und versuchen das in ihren Programmen. Das funktioniert dann
                            nicht und schon haben wir einen neuen Thread mit neuer Frage im
                            Forum, und das nur, weil ein kleiner Fehler nicht gleich da
                            korrigiert wurde, wo er entstanden ist. Du kannst dir vorstellen,
                            dass dies im Worst-Case eine exponenzielle Kettenreaktion hervorrufen
                            kann :-)

                            Natürlich soll man jetzt auch nicht hingehen und jeden noch so
                            kleinen Fehler korrigieren, das würde am Ziel auch
                            vorbeischiessen. Die Entscheidung was korrigiert werden soll, muss
                            jeder Poster für sich selber entscheiden. Aber *das* einige Fehler
                            korrigiert werden obwohl jeder (oder eben *fast* jeder) den Inhalt
                            verstanden hat, kann manchmal wirklich richtig sein.

                            Nun ja, von Zeit zu Zeit entscheide auch ich mich dazu, ob hier der
                            richtige Zeitpunkt war, darf natürlich angezweifelt werden :-)

                            tz tz tz :-)

                            Ach, geh schlafen! :-)

                            Viele Grüsse

                            Philipp

                            1. Moin moin Philipp,

                              Mal im Ernst, diese kleinen Fehler werden ins Archiv verschoben und
                              ggf. von Suchenden gefunden. Sie lesen, dass s/\n//; alle Zeilenumbrüche
                              löscht und versuchen das in ihren Programmen. Gruß,

                              von dieser Seite hatte ich das bisher noch nicht betrachtet! Ich werde mir das zu Herzen nehmen und Fehler Anderer, wenn ich dann mal online bin und welche finde... kritisieren, aber freundlichst.

                              Aber zunächst sollte ich dann wohl bei mir selbst anfangen :-)

                              Bis dann...

                              coolblue

                              --
                              never say oops after you submitted a job :-)
                              _der_Ton_macht_die_Musik_!!!_
                            2. Halihallo Philipp,

                              Mal im Ernst, diese kleinen Fehler werden ins Archiv verschoben und
                              ggf. von Suchenden gefunden. Sie lesen, dass s/\n//; alle Zeilenumbrüche
                              löscht und versuchen das in ihren Programmen. Das funktioniert dann
                              nicht und schon haben wir einen neuen Thread mit neuer Frage im
                              Forum, und das nur, weil ein kleiner Fehler nicht gleich da
                              korrigiert wurde, wo er entstanden ist. Du kannst dir vorstellen,
                              dass dies im Worst-Case eine exponenzielle Kettenreaktion hervorrufen
                              kann :-)

                              Ich hab mir schon mehrmals eine Funktion im Forum gewünscht, mit der ich ein schon abgeschicktes Posting nachträglich korrigieren kann. Die Vorschaufunktion hilft bei solchen Schusselfehlern leider nicht :(

                              Nun ja, von Zeit zu Zeit entscheide auch ich mich dazu, ob hier der
                              richtige Zeitpunkt war, darf natürlich angezweifelt werden :-)

                              War er. Ich hätte es sonst nicht gemerkt. Aber ich entferne die (letzten) Zeilenumbrüche (in einem String) sonst auch immer mit chomp(). ;-)

                              Viele Grüsse

                              Dir auch.

                              1. 你好 EisFux,

                                Ich hab mir schon mehrmals eine Funktion im Forum gewünscht, mit der ich
                                ein schon abgeschicktes Posting nachträglich korrigieren kann. Die
                                Vorschaufunktion hilft bei solchen Schusselfehlern leider nicht :(

                                Wird es nicht geben, kann es auch nicht geben. Gruende finden sich im
                                Archiv.

                                再见,
                                 CK

                                --
                                Das Leben ist wie ein Kartenspiel: was dir gegeben wurde, ist vorbestimmt. Doch wie du damit spielst, ist deine Entscheidung.
                                http://wwwtech.de/
                          2. Hallo coolblue,

                            Nö, das wäre $command =~ s/\n//g;

                            das ist echt fieß von dir! Ich dachte schon daran, ihn darauf aufmerksam zu machen, weil es mir auch aufgefallen war, habe aber den Mund gehalten, weil ich kürzlich dich noch darum bat, sowas nicht zu tun...

                            Hättst du es mal getan. Kritik ist nicht fies, sondern notwendig. Wer nicht ab und zu (berechtigt) kritisiert wird, hält sich irgendwann für den größten Superhelden. Ab und zu verbal ein paar hinter die Löffel bringen einen wieder auf den Boden der Tatsachen zurück. Und wer nichts macht, macht auch keine Fehler.

                            Gruß,
                            EisFuX

                        2. Halihallo Philipp Hasenfratz,

                          Nö, das wäre $command =~ s/\n//g;

                          Ja richtig, ich habe das kleine g verschusselt. Kein Wunder bei der Uhrzeit ...

                          =~ s/\n//; entfernt nur einen Zeilenumbruch und das ist - wie
                          coolblue - richtig feststellt genau der Letzte.

                          Ähm, wenn ich mal vorsichtig berichtigen dürfte:
                          Nein, es entfernt den ersten, der im String auftaucht, chomp() dagegen den letzen. Aber das nur so nebenbei.

                          Im Übrigen ist das Verhalten von chomp() stark von der Variablen $/ abhängig. Es hackt nicht immer den letzen Zeilenumbruch weg. Wobei Zeilenumbruch ja auch nur eine ungefähre Umschreibung von Ausdrücken wie "\n" oder "$/" ist. ;-)

                          Aber wie ich bereits sagte, =~ s/\n$//; ist noch performanter, da der
                          Zeilenumbruch nicht erst gefunden werden muss, sondern nur das letzte
                          Zeichen mit \n verglichen werden muss und falls es denn gleich ist,
                          wird es "weg-replaced".

                          Nur mal interessehalber: Macht sich der Performanceunterschied auch in normalen Webanwendungen bemerkbar (Ausführungszeit, Speicherverbrauch)? Da vertrödelt ein Perl-Skript die meiste Zeit doch sowieso damit, auf den Datenbankserver zu warten ...

                          Viele Grüsse

                          Genau, die vergess ich immer am Schluss.

                          1. Halihallo EisFux

                            =~ s/\n//; entfernt nur einen Zeilenumbruch und das ist - wie
                            coolblue - richtig feststellt genau der Letzte.

                            Ähm, wenn ich mal vorsichtig berichtigen dürfte:
                            Nein, es entfernt den ersten, der im String auftaucht, chomp() dagegen den letzen. Aber das nur so nebenbei.

                            Richtig.

                            Im Übrigen ist das Verhalten von chomp() stark von der Variablen $/ abhängig. Es hackt nicht immer den letzen Zeilenumbruch weg. Wobei Zeilenumbruch ja auch nur eine ungefähre Umschreibung von Ausdrücken wie "\n" oder "$/" ist. ;-)

                            Genau. Deswegen sollte man ja chomp() verwenden, sonst müsste man
                            jedesmal wenn die Definition von "Zeilenumbruch" ändert, die RegExp
                            anpassen.

                            Aber wie ich bereits sagte, =~ s/\n$//; ist noch performanter, da der
                            Zeilenumbruch nicht erst gefunden werden muss, sondern nur das letzte
                            Zeichen mit \n verglichen werden muss und falls es denn gleich ist,
                            wird es "weg-replaced".

                            Nur mal interessehalber: Macht sich der Performanceunterschied auch in normalen Webanwendungen bemerkbar (Ausführungszeit, Speicherverbrauch)? Da vertrödelt ein Perl-Skript die meiste Zeit doch sowieso damit, auf den Datenbankserver zu warten ...

                            Du hast dir die Frage bereits beantwortet: Der Performanceunterschied
                            ist verschwindenst klein. Du sparst bei 3.2 Mio. Scriptaufrufen
                            ziemlich genau nur 1 CPU-Sekunde :-)

                            Viele Grüsse

                            Philipp

                            1. Halihallo

                              Du hast dir die Frage bereits beantwortet: Der Performanceunterschied
                              ist verschwindenst klein. Du sparst bei 3.2 Mio. Scriptaufrufen
                              ziemlich genau nur 1 CPU-Sekunde :-)

                              Äm, auch meinem Computer zumindest (Pentium 4 mit 2.25 GHz)... Wenn
                              schon genau berechnen, dann auch halbwegs genau beschreiben...

                              Viele Grüsse

                              Philipp

  2. Halihallo coolblue

    weder fork noch exec scheinen mir bei meinem Problem weiter zu helfen, wenn doch, dann habe ich etwas nicht verstanden oder völlig falsch gemacht.

    Es wäre gut einen Link auf vorherige Postings zu haben, wo das Thema
    anscheinend schon erörtert wurde.

    Der Server soll den Befehl oder den Prozess ausführen und danach weiterhin auf den Port lauschen, um gegebenfalls weitere "Befehle" auszuführen. Er soll nicht auf das Ende des Prozesses warten. Das Problem ist nun, dass der Server an der Stelle, an der er den system Befehl ausführt, solange hängt, bis der mit system gestartete Prozess gekillt wird oder sich selbst beendet.

    Das wiederspiegelt sich in deinen Programmen. Ich komme gleich
    dazu...

    while($client = $server->accept()) {
       $command=<$client>;
       ***system Befehl***
    }

    Hier ist wohl klar, dass er immer auf Beendigung von system() wartet,
    da kein fork verwendet wird; system wartet immer auf das Beenden des
    Prozesses, auch wenn da ein & steht...

    system('$command &');

    Nicht probieren, wissen. Variablen werden nur in Doublequotes
    aufgelöst...

    use POSIX;

    wofür?

    while($client = $server->accept()) {
       $command=<$client>;
       $pid = fork;
       exit if $pid;
       system("$command &");
    }

    Also:

    Server lauscht...
    Server erhält connection -> $client
    *Server* wird beendet (was er nicht soll!).
    Client führt $command aus und lauscht dann weiter.

    Das wird besser so gemacht:

    while ( $client = $server->accept()) {
        $command = chomp(<$client>);
        $pid = fork();
        die('cannot fork!') unless (defined($pid));
        unless ($pid) {   # also Child...
            system("$command");  # ... führt Befehl aus...
            exit;         # ... und stirbt dann.
        }
        # und Parent lauscht gleich weiter!
    }

    So, damit sollte es dann funktionieren.

    Viele Grüsse

    Philipp

    1. Supi, danke für deine Hilfe, aber

      » Das wird besser so gemacht:
      »
      » while ( $client = $server->accept()) {
      »     $command = chomp(<$client>);
      »     $pid = fork();
      »     die('cannot fork!') unless (defined($pid));
      »     unless ($pid) {   # also Child...
      »         system("$command");  # ... führt Befehl aus...
      »         exit;         # ... und stirbt dann.
      »     }
      »     # und Parent lauscht gleich weiter!
      » }
      »
      » So, damit sollte es dann funktionieren.

      Leider nicht so wie ich es gemeint hatte. Der Child-Prozess wartet solange, bis der $command Prozess beendet ist. Folgendes Szenario:

      Ich sende 100 mal den Befehl "sar -u 1 100" an den Server. Dann habe ich 100 Mal den sar Befehl gestartet => korrekt. Aber dann habe ich auch 100 Child Prozesse, die auf das Ende ihrer sar Prozesse warten. Nun gibt es allerdings Prozesse die eventuell gestartet werden, welche nonstop laufen. Ich möchte nicht, dass die Child Prozesse existieren. Ich möchte den $command Befehl absetzen, ohne das ein Child Prozess bis zum bitteren Ende existiert.

      Gruß,
      coolblue

      --
      never say oops after you submitted a job :-)
      1. Halihallo coolblue

        Ich sende 100 mal den Befehl "sar -u 1 100" an den Server. Dann habe ich 100 Mal den sar Befehl gestartet => korrekt. Aber dann habe ich auch 100 Child Prozesse, die auf das Ende ihrer sar Prozesse warten. Nun gibt es allerdings Prozesse die eventuell gestartet werden, welche nonstop laufen. Ich möchte nicht, dass die Child Prozesse existieren. Ich möchte den $command Befehl absetzen, ohne das ein Child Prozess bis zum bitteren Ende existiert.

        Ach so ist das... Also:

        use POSIX qw(setsid);

        while ( $client = $server->accept()) {
            $command = chomp(<$client>);
            $pid = fork();
            die('cannot fork!') unless (defined($pid));
            unless ($pid) {   # also Child...
                setsid();     # ... wird vollkommen von Parent getrennt
                exec("$command");  # ... und mit $command Befehl "ersetzt"
            }
            # und Parent lauscht gleich weiter!
        }

        Viele Grüsse

        Philipp

        1. Hola, et funzt...

          »
          » Ach so ist das... Also:
          »
          » use POSIX qw(setsid);
          »
          » while ( $client = $server->accept()) {
          »     $command = chomp(<$client>);
          »     $pid = fork();
          »     die('cannot fork!') unless (defined($pid));
          »     unless ($pid) {   # also Child...
          »         setsid();     # ... wird vollkommen von Parent getrennt
          »         exec("$command");  # ... und mit $command Befehl "ersetzt"
          »     }
          »     # und Parent lauscht gleich weiter!
          » }
          »
          » Viele Grüsse
          »
          » Philipp

          Nur eine Sache noch, dein chomp funktioniert nicht.
          Meldung: cant modify handle in chomp ... (<$client>)

          Gruß,
          coolblue

          --
          never say oops after you submitted a job :-)