Tom: Laufzeit von Scripten

Hello,

ich habe da noch ein Problem mit der Laufzeit von Scripten.

Ein lange laufendes Script soll während des Laufens Ausgaben auf den Client schicken. Das klappt nur sporadisch.
Das Script soll abbrechen, wenn am Client auf Stop geklickt wird. Geht das überhaupt? Ich kann leider die PHP-Funktionen für die User-Alive-Abfrage nicht wiederfinden. Oder habe ich die nur geträumt?

Hier zur Verdeutlichung das Script:

<?php  #### bigfile.php ###

set_time_limit(600);

define("ZEICHENSATZ","abcdefghijklmnopqrstuvwxyzäöüßABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜ0123456789-+_&~.,! ");

#-------------------------------------------------------------------------
function get_random_str($lenmin,$lenmax)
{
  mt_srand ((double)microtime()*1000000);
  $anzahl = mt_rand($lenmin,$lenmax);

$zeichen=ZEICHENSATZ;

$zufall="";

$i=0;
  while($i<=$anzahl)
  {
    $zufall.=substr($zeichen,mt_rand(0,strlen($zeichen)-1),1);
    $i++;
  }
  return $zufall;
}

#-------------------------------------------------------------------------
function make_bigfile($filename)
{
  $data = "";
  for($i=0;$i<1000;$i++)
  {
    $data .= get_random_str(400,1500)."\r\n";
  }

$fp = fopen("$filename","a+");
  fwrite($fp,$data);
  fclose($fp);
}

#-------------------------------------------------------------------------

umask(0);
@mkdir("../bigfiles",0775);

echo "Dateien werden erzeugt <br />";
flush();
flush();

for ($i=1;$i<101;$i++)
{
  $filename = "../bigfiles/file_".str_pad ( "$i", 3, "0",STR_PAD_LEFT)."dat";
  if (!file_exists($filename))
  {
    make_bigfile($filename);
    #chgrp($filename,"team");
    echo "file $i<br />";
    flush();
    flush();
  }
}

?>

Liebe Grüße aus http://www.braunschweig.de

Tom

--
Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
  1. Hi,

    zuerst mal nein, denn PHP läuft ja auf dem Server.

    Aber wenn du vielleicht eine Seite mit einem iframe machst, könntest du einfach, wenn der Benutzer auf stopp klickt im iframe eine andere (evt. leere) Seite laden.

    Andy

  2. hi,

    Das Script soll abbrechen, wenn am Client auf Stop geklickt wird. Geht das überhaupt? Ich kann leider die PHP-Funktionen für die User-Alive-Abfrage nicht wiederfinden. Oder habe ich die nur geträumt?

    hast du eventuell von ignore_user_abort geträumt?
    http://de2.php.net/ignore_user_abort

    gruss,
    wahsaga

    1. Hello,

      Das Script soll abbrechen, wenn am Client auf Stop geklickt wird. Geht das überhaupt? Ich kann leider die PHP-Funktionen für die User-Alive-Abfrage nicht wiederfinden. Oder habe ich die nur geträumt?

      hast du eventuell von ignore_user_abort geträumt?
      http://de2.php.net/ignore_user_abort

      Ja, danke. Davon hatte ich geträumt. Mal sehen, ob es auch funktioniert.

      Ich habe da noch eine Merkwürdigkeit festgestellt bezüglich des flush() und des file_exists(). Die funktionieren nicht mehr, wenn vorher ein Fehler aufgetreten ist. Könnte sein, dass das daran liegt, dass ich @BEFEHL benutze und $php_errormsg nicht abfrage. Hast Du dazu auch eine Idee?

      Liebe Grüße aus http://www.braunschweig.de

      Tom

      --
      Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
      1. Hello,

        ...und noch ein Test:

        <?php #### connection.php ####

        Testet auf Userabort

        set_time_limit(1);

        echo "<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.1 Transitional//EN">\n";
        echo "<HTML>\n";
        echo "<HEAD>\n";
        echo "  <TITLE>Dauerlauf</TITLE>\n";
        echo "</HEAD>\n";
        echo "<BODY>\n";

        $ok = ignore_user_abort();
        echo $ok."<br />";

        while (!connection_aborted())
        {
          $dir = @mkdir("test");
          $fehler = $php_errormsg;

        echo getmypid()." ".time()." $fehler ".(($dir===false)?"FALSE":"TRUE")."<br />";
          flush();
          sleep(1);
        }

        echo "</body>\n";
        echo "</html>";
        ?>
        ----------------------------------------------------

        Dieses Script läuft nun schon ewig auf diversen Plätzen in diversen Browserfenstern. Der Server lacht nur drüber... ->kaum Last.

        Das mkdir() sthet eigetlich nur dirn, um einen Fehler zu provozieren. Der bleibt aber aus. Allerdings reagiert die Funktion durchaus auf Anlegen können oder nicht (True/False).

        Woran kann es leigen, dass im Client bei Erstaufruf des Scriptes ca. vier bis fünf Sekunden nichts erscheint und dann der ganze Buffer auf einmal angezeigt wird (die ersten Zeilen eben)? Wenn man Reload klickt, reagieren die Browser aber sofort mit Ausgabe.

        Woran kann es liegen, dass das Time-Limit nicht anschlägt? Ist die echte Ausführungszeit wirklich soooo gering, oder wird Time-Limit durch sleep() außer Gefecht gesetzt / rückgestzt. Ich habe zwar die Usernotes von PHP.net gelesen, aber so richtig genau scheint das ja niemand zu wissen...

        Liebe Grüße aus http://www.braunschweig.de

        Tom

        --
        Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
        1. hi,

          Woran kann es liegen, dass das Time-Limit nicht anschlägt? Ist die echte Ausführungszeit wirklich soooo gering, oder wird Time-Limit durch sleep() außer Gefecht gesetzt / rückgestzt. Ich habe zwar die Usernotes von PHP.net gelesen, aber so richtig genau scheint das ja niemand zu wissen...

          also zumindest das geht für mich aus dem ersten userkommentar unter http://www.php.net/manual/de/function.sleep.php doch recht deutlich hervor, direkt im ersten steht:

          "Note: The set_time_limit() function and the configuration directive max_execution_time only affect the execution time of the script itself. Any time spent on activity that happens outside the execution of the script such as system calls using system(), the sleep() function, database queries, etc. is not included when determining the maximum time that the script has been running."

          sleep() wird also _nicht_ in die berechnung der scriptlaufzeit mit einbezogen.

          das klingt für mich auch logisch, und die restlichen kommentare auf dieser seite widersprechen dem auch nicht (sondern lassen sich darüber aus, ob man sleep() bei login-mechanismen einsetzen sollte, um brute-force-angriffe zu erschweren).

          gruss,
          wahsaga

          1. Hello,

            also zumindest das geht für mich aus dem ersten userkommentar unter http://www.php.net/manual/de/function.sleep.php doch recht deutlich hervor, direkt im ersten steht:

            sleep() wird also _nicht_ in die berechnung der scriptlaufzeit mit einbezogen.

            Das habe ich auch bisher immer gedacht, dass es so wäre. Nur schau doch mal in mein kleines Script rein. Ich habe als Timelimit 1 Sekunde angegeben und das Script lief Stunden. Sooo wenig Rechenzeit kann das gar nicht kosten, insbesondere, wenn ein Filesystem-Zugriff dabei ist.

            Das andere Script, dass die 100 Monsterdateien mit Zufallswerten erzeugt hat, hatte 600 Sekunden Laufzeit und KEIN Sleep und ist auch nach 600 Sek. abgeschossen worden...

            Deshalb vermute ich eben, dass der Timeout-Counter durch Sleep() zurückgestzt wird.

            Liebe Grüße aus http://www.braunschweig.de

            Tom

            --
            Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
            1. hi,

              Deshalb vermute ich eben, dass der Timeout-Counter durch Sleep() zurückgestzt wird.

              wäre zumindest denkbar.

              der timeout ist ja nicht zuletzt dafür da, dem server eine zu hohe, dauerhafte belastung zu ersparen.

              wenn jetzt aber durch sleep() eine "ruhephase" im script eingebaut ist, hat der server ja zwischendurch noch einiges an ressourcen für andere aufgaben frei, überarbeitet sich also nicht so schnell.

              wie gesagt, _könnte_ plausibel sein - aber nix genaues weiss ich da nicht.

              gruss,
              wahsaga

              1. Hello,

                wäre zumindest denkbar.

                der timeout ist ja nicht zuletzt dafür da, dem server eine zu hohe, dauerhafte belastung zu ersparen.

                wenn jetzt aber durch sleep() eine "ruhephase" im script eingebaut ist, hat der server ja zwischendurch noch einiges an ressourcen für andere aufgaben frei, überarbeitet sich also nicht so schnell.

                wie gesagt, _könnte_ plausibel sein - aber nix genaues weiss ich da nicht.

                Ja. Wie könnte man das jetzt rauskriegen? Ich habe schon alles durchgewühlt, ob PHP irgendwo eine Funktion für die Ermittlung der echten Execution-Time-Sum zur Verfügung stellt, aber denkste.

                Bleibt im Prinzip nur die Prozessbeobachtung unter Linux. Die PID bleibt ja für den ganzen Vorgang gleich.

                Gestaunt habe ich heute, was Server an unterschiedlichen Ausführungszeiten im Filesystem haben können. Unser Provider war beim TAR-archivieren mindestens 5 mal so schnell, wie unser Testsewrver im Büro.

                Allerdings hat er bei PHP nur 28% mehr Speed drauf gehabt.

                Liebe Grüße aus http://www.braunschweig.de

                Tom

                --
                Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen