1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen

Warten in Warteschleife

Dieses Thema im Forum "PHP" wurde erstellt von Alice, 27. April 2012.

  1. Alice

    Alice Erfahrenes Mitglied

    Hallo. :)

    Ich hatte zwar schon einmal ein ganz ähnliches Thema, jedoch möchte ich die Diskussion neustarten aus diversen Gründen.

    Ich habe meinen Verkehrzeichen Generator (Generiert Verkehrzeichen wie Straßenschilder) ausgibig getestet und habe festgestellt das wenn man den Generator mehrmals ausführt (in verschiedenen Tabs) sich die Ausführzeit immer um ca. 2-3 Sekunden erhöht.

    1. Run - Straßenschild -> 4-5 Sekunden
    2. Run - Stop-Shild -> 7-8 Sekunden
    3. Run - Autobahnschild -> 9-10 Sekunden

    Wenn ich jeweils nur ein Schild erstelle, braucht das Skript nie länger wie 4-5 Sekunden.

    1. Frage:

    Jetzt habe ich erst einmal zu der Ausführzeit eine Frage.
    Ich weiss jetzt nicht genau warum sich die Ausführzeit immer um 2-3 Sekunden pro Schild erhöht? Liegt es am Server (Power) oder liegt es evtl. auch am Dateinamen?

    Beispiel:
    Server -> schilder-generator-deutschland.php
    Server -> schilder-generator-schweiz.php

    Sagen wir das Skript "schilder-generator-deutschland.php" wäre 5 mal gleichzeitig am laufen. Dann würde sich die Ausführzeit ja immer (im besten Fall) um 2-3 Sekunden verlängern.

    schilder-generator-deutschland.php:
    1. Run -> 4-5 Sekunden
    2. Run -> 7-8 Sekunden
    3. Run -> 9-10 Sekunden
    4. Run -> 12-13 Sekunden
    5. Run -> 15-16 Sekunden

    Wie lange würde dann "schilder-generator-schweiz.php" laufen wenn ich es direkt nach dem 5. Run starten würde? Würde die Ausführungzeit wie bei "schilder-generator-deutschland.php" immer proportional ansteigen oder würde der Server den anderen Generator als "neuen Task" oder so bearbeiten und wäre in 4-5 Sekunden fertig? Oder würde das andere Skript (schweiz) 18-19 Sekunden laufen?

    2. Frage:

    Ich weiss nicht mehr genau ob ich diese Idee hatte, oder ob mir das jemand vorgeschlagen hat. Jedenfalls wäre es evtl. ganz Sinnvoll eine Warteschleife in das Skript einzubauen.

    Die Idee:
    Wenn der Generator gestartet wird, wird eine "1" in die DB geschrieben. Wenn das Skript fertig ist (ganz am Ende) wird die zuvor eingetragene "1" in "0" geändert. Solange eine "1" eingetragen ist, kann das selbe Skript nicht noch einmal ausgeführt werden.

    Dieser Teil ist ja simpel zu programmieren aber wie mache ich das mit der Warteschleifen? Denn die Eingaben des User sollen ja nicht gelöscht werden und aus der "Run-Befehl" soll nicht gelöscht werden. Also Sachen wie "probieren sie es später" usw. sind nicht mein ding.

    Hat hier jemand eine Idee wie ich das machen könnte?

    Danke im Vorraus.
    Zuletzt bearbeitet: 27. April 2012
  2. sheel

    sheel Mod # I love Asm Moderator

    Hi

    Du meinst hoffentlich gleichzeitig?

    Weiss ja nicht, was du da machst, aber das ist nicht schnell.

    Der Dateiname hat damit gar nichts zu tun, aber eben die Leistung.

    Ein Arbeiter mit Schaufel braucht für ein Loch eine Stunde.
    Wie lange braucht er für 2 Löcher? ...

    Warum probierst du es nicht einfach?
    Alle Scripts teilen sich den gleichen Computer.
    Wenn Schweiz gleichzeitig mit 5 Deutschlands rennt ist Schweiz auch langsam.

    Gar nicht.
    PHP, Apache, der Browser etc. haben Timeouts.
    Du kannst nicht beliebig lang warten, nach einigen Sekunden
    sagt der Browser "schluss, will nicht mehr", Fehlermeldung.
  3. Alice

    Alice Erfahrenes Mitglied

    Ja...

    Natürlich ist das nicht schnell. Wenn man aber berücksichtigt das im Hintergrund eine 8000x5000px große Grafik generiert wird (SVG -> PNG) und diese dann auch noch mit ImageMagick in die Richtige Ausgabegröße getrimmt wird, ist das nicht wirklich langsam.

    Nebenbei wird auch ein etwas aufwändigeres Wasserzeichen generiert. Ein Text im Kreis mit ca. 100 Zeichen.

    1. SVG erstellen
    2. Wasserzeichen erstellen
    3. SVG bearbeiten
    4. SVG zu PNG konvertieren
    5. PNG skallieren

    Ohne den IMagick-Befehle zum konvertieren (SVG zu PNG) und zum Skalieren der PNG braucht das Skript lediglich nur noch 0,21007 Sekunden.

    Bei dieser Zeit kann man nicht meckern und es zeigt auch, dass das Skript "sauber" programmiert ist.

    Die längere Ausführungszeit liegt definitiv an der konvertierung von SVG nach PNG. Der Teil zum skallieren der Grafik wird schnell abgearbeitet.

    Mit "exec" dauert es sogar noch länger. Mit Inkscape würde es sogar doppelt so lange wie mit "exec" dauern und "Batik" kann ich auf den Server nicht installieren, aber von "Batik" weiss ich das es auch länger braucht.

    Es gibt also keine Alternative zu "Imagick".

    Die Warteschleife soll ja nicht Minuten oder Stunden lang laufen. Vielleicht 60 oder 90 Sekunden als Maximum.

    Wie machen das denn andere Dienste mit Serverlastigen Projekten? Es ist einfach ein aufwändiges Verfahren.

    Edit:

    Hallo noch einmal.

    Ich habe mi folgendes überlegt.

    Der User füllt das Formular aus und verschickt es. Es wird in der DB überprüft ob eine "1" eingetragen ist. Wenn ja, dann wird eine Schleife im Skript aktiviert, die solange in dieser Schleife bleibt, bis der Wert "0" ist. Wenn das ganze zu lange dauert, bekommt der User halt nach ca. 1 Minute einen Timeout.

    Nur wie kann ich es regeln das der nächste User auch wirklich der nächste User ist?

    Da muss es doch ne Lösung für geben?

    Wie @Shell schon sagte sind 4-5 Sekunden nicht wenig und meine User benutzen den alten Generator (ganz einfach programmiert) manchmal 50 mal auf einmal. Das weiss ich weil ich unter anderem den Timestamp in der DB speichere.

    Ich persöhnlich kenne jetzt auf Anhieb nur eine Webseite die auch Rechenintensive Skripte nutzt (auch Grafik verabeitung) und die setzen auch eine Warteschlage ein. Jedoch basiert die Seite komplett auf JS. Zumindest habe ich das so in deren Forum gelesen.

    Edit:

    Sorry für Doppelpost. Ich hätte schwören können, das ich auf Edit geklickt habe.
  4. sheel

    sheel Mod # I love Asm Moderator

    Wenn das Timeout also akzeptabel ist, ein Hinweis zum SQL:
    Beim Warten und dann 1 setzen:

    Nicht in der Schleife prüfen ob 1, ob 1...und dann
    wenns 0 ist mit einer zweiten SQL-Anweisung auf 1 setzen.
    Problem dabei: Zwei/mehrere merken, es ist gerade auf 0 gegangen.
    Alle von denen beenden die Schleife.
    Einer setzt sein 1 rein.
    Der Nächste setzt auch 1 und denkt, er ist dran, weil er nicht gemerkt hat,
    dass schon wieder 1 drin war.

    Besser:
    Code (SQL):
    1.  
    2. UPDATE ... SET x=1 WHERE x=0
    3.  
    und dann affected_rows überprüfen (beides in der Schleife).
    Wenn dieses 0 ergibt: Schleife weiter
    1: Konvertierung beginnen.

    Was bedeutet das?

    Wäre eine Möglichkeit.
    PHP-Script erzeugt zeurst eine Bitte-warten-Seite
    und speichert in der DB eine Liste von Bildern, die noch abgearbeitet werden müssen.
    Die Bitte-warten-Seite fragt per Ajax alle 1-2 Sekunden ab, ob ihr Bild fertig ist,
    und wechselt ggf. zur Ergebnisseite.

    Das kann man doch auch nachträglich bearbeiten, ist hiermit geschehen.
  5. Alice

    Alice Erfahrenes Mitglied

    Hallo. :)

    Ich habe leider noch keine Idee wie ich das gut lösen kann.

    Eine provisorische Idee wäre mittels JS z.B. 10 Sekunden nach Skript-Start einen Text einzublenden das der Vorganz sich verzögert.

    Nur wie umsetzen?

    Edit:

    Ich weiss wie ich das mit JS lösen könnte. Jedoch soll die Funktion mit dem Submit-Button verbunden sein.
    Zuletzt bearbeitet: 29. April 2012
  6. saftmeister

    saftmeister Nutze den Saft! Premium-User

    Wenn dein Edit eine Frage sein soll: Es gibt für alle möglichen Form-Elemente das Attribut "onclick", dem man eine JS-Funktion zuweisen kann.
  7. Alice

    Alice Erfahrenes Mitglied

    Ich möchte mit der Funktion "timeout" nach 5 Sekunden ein DIV-Container einblenden.

    Code ( (Unknown Language)):
    1.  
    2. function toogle (id) {
    3.     var obj = document.getElementById(id);
    4.     var defaultClassName = obj.className;
    5.     return function () {
    6.         obj.className = obj.className == "hidden" ? defaultClassName : defaultClassName + " hidden";
    7.     }    
    8. }
    9. window.onload = function () {
    10.     setTimeout(toogle("eine_id"), 1000);
    11.     setTimeout(toogle("zwei_id"), 2000);
    12. }
    13.  
    Die Zeit für den Timeout soll aber erst runtergezählt werden, wenn auf den Submit-Button geklickt wurde.

    Kannst du mir dabei helfen?
  8. saftmeister

    saftmeister Nutze den Saft! Premium-User

    Dann nimm die onload-Lambda raus und erstelle eine separate Funktion, die du im onclick-Attribut aufrufst. Z.B. so:

    Code (HTML5):
    1.  
    2. <script type="text/javascript">
    3. function toogle (id) {
    4.     var obj = document.getElementById(id);
    5.     var defaultClassName = obj.className;
    6.     return function () {
    7.         obj.className = obj.className == "hidden" ? defaultClassName : defaultClassName + " hidden";
    8.     }    
    9. }
    10. timeout_handler() {
    11.     setTimeout(toogle("eine_id"), 1000);
    12.     setTimeout(toogle("zwei_id"), 2000);
    13.  
    14.     return true;
    15. }
    16.  
    17. <form action....>
    18.   ....
    19.   <input type="submit" onclick="return timeout_handler();"/>
    20. </form>
    21.  
    EDIT: Evtl verwendest du settimeout() nicht richtig. Hier ist ein Beispiel: http://de.selfhtml.org/javascript/objekte/window.htm#set_timeout

    Das würde bedeuten, das man als ersten Parameter an settimeout() einen String übergeben muss. Ich bin mir nicht sicher, ob dass, wie du es machst, korrekt ist oder nicht - da ich kein JS-Experte bin :)
    Zuletzt bearbeitet: 29. April 2012
  9. Alice

    Alice Erfahrenes Mitglied

    Hallo. :)

    Mich würde es interessieren wie ImageMagick auf dem Server mit mehreren Aufgaben umgeht?

    Ich kann ja in mehreren Tabs z.B. den Verkehrszeichen-Generator starten und es werden dann ja in wenigen Millisekunden mehrere SVG-Dateien erstellt. Nur wie geht ImageMagick beim konvertieren der SVG-Dateien zu PNG-Grafiken vor?

    Werden die SVG-Dateien hintereinander konvertiert oder je nach Startzeit auch gleichzeitig?

    Denn die Antwort auf diese Frage interessiert mich aus folgendem Grund sehr: Wenn die SVG-Grafiken je nach Startzeit NACHEINANDER abgearbeitet werden, befinden sich die anderen SVG-Dateien ja sowieso in einer Warteschlange oder sehe ich das falsch?
  10. sheel

    sheel Mod # I love Asm Moderator

    Mehrere exec gleichzeitig starten mehrere Instanzen,
    die unabhängig voneinander arbeiten.
  11. Alice

    Alice Erfahrenes Mitglied

    Was heisst das genau?

    Es werden also NICHT alle Dateien nacheinander abgearbeitet sondern u.U. gleichzeitig?

    Arbeitet die Imagick PHP-Extension auch mit exec?

    Edit:

    Wenn ich mit der Windows-Konsole (Windows 7) SVG-Dateien konvertiere (mit Inkscape) werden alle Dateien nacheinander abgearbeitet. Das kann man dann auch super am Bildschirm sehen.
  12. sheel

    sheel Mod # I love Asm Moderator

    Wahrscheinlich schon.
    Hängt aber von hunderten Details ab.

    Warum probierst du es nicht einfach?
    Lass 100 möglichst große, langsame Dateien durch (nicht in PHP warten, bis eins fertig ist, sondern alles starten) und schau dann auf das Dateierstellungs/änderungsdatum.
    Da kann man dann entsprechende Rückschlüsse ziehen.
    Keine Ahnung.

    Ja, wweil das eine Konsole ist.
    Mehrere PHP-Scripts, jedes für einen Benutzer, existieren gleichzeitig nebeneinander.
  13. Alice

    Alice Erfahrenes Mitglied

    Hallo. :)

    Ich denke das die SVG-Dateien nacheinander und nicht gleichzeitig ins PNG-Format konvertiert werden.

    Alle vier Skripte mit wenigen Millisekunden unterschied gestartet.

    1. 2,35023 Sekunden
    2. 3,61729 Sekunden
    3. 4,49119 Sekunden
    4. 5,62234 Sekunden

    Laut Filezilla wurden die Dateien wie folgt erstellt:
    1. 20.13:45 Uhr
    2. 20.13:47 Uhr
    3. 20.13:50 Uhr
    4. 20.13:52 Uhr

    Ich muss jedoch erwähnen das ich den IMagick-Code etwas optimiert habe.

Diese Seite empfehlen