Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] phtreads done

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • [Erledigt] phtreads done

    http://www.php.net/manual/en/threaded.wait.php

    Hat wer eine Idee, warum man die Eigenschaft "done" benötigt? Es funktioniert scheinbar auch ohne.

    PHP-Code:
    <?php
       error_reporting
    (~0);
       
       class 
    My extends Thread 
       
    {
          
    //public $done = false;
          
          
    public function run() 
          {
             
    /** cause this thread to wait **/
             
    $this->synchronized
             
    (
                
    /**
                 * Closure
                 * @param My $thread Die eigene Instanz
                 */
                
    function(My $thread// closure
                
    {
                   
    //var_dump('wait 0: '.($this->done ? 'true' : 'false'));
                   //if(!$thread->done)
                   //{
                      
    var_dump('wait');
                      
    $thread->wait(); // in Schlaf versetzen
                   //}
                
    }, 
                
    $this
             
    );
          }
       }
       
       
    $my = new My();
       
    $my->start();
       
       
    // Darauf warten, dass der neue Thread auch tatsächlich in den Schlafmodus versetzt wurde:
       
    sleep(1);
       
       
    /** send notification to the waiting thread **/
       
    $my->synchronized
       
    (
          
    /**
           * Closure
           * @param My $thread Die eigene Instanz
           */
          
    function(My $thread// closure
          
    {
             
    var_dump('is waiting 0: '.($thread->isWaiting() ? 'true' 'false'));
             
    //$thread->done = true;
             
    $thread->notify(); // aus Schlaf erwecken
          
    }, 
          
    $my
       
    );
       
    var_dump('is waiting 1: '.($my->isWaiting() ? 'true' 'false'));
       
       
    var_dump($my->join());
    ?>
    Ergebnis:
    string(4) "wait"
    string(1 "is waiting 0: true"
    string(19) "is waiting 1: false"
    bool(true)

  • #2
    Nicht, wenn der zweite Thread zuerst durchläuft, bzw. das notify() ausgeführt wird, bevor das wait() ausgeführt wird.
    [QUOTE=nikosch]Macht doch alle was Ihr wollt mit Eurem Billigscheiß. Von mir aus sollen alle Eure Server abrauchen.[/QUOTE]

    Kommentar


    • #3
      Da hast du Recht!

      Ich hatte mir zuvor auch https://gist.github.com/krakjoe/6437782 durchgelesen.
      In the notification example, you ensure that the context that is waiting is not left hanging around forever because if you have acquired the synchronization lock and the object is not waiting then it need not wait
      Ich versuche das mal zu übersetzen:
      In dem Aufwach-Beispiel stellt man sicher, dass der wartende Kontext nicht hängengelassen wird. Hat man nämlich den Synchronisierung-Lock erreicht und das Objekt warten nicht, dann braucht es auch nicht zu warten.
      Ohne dem done würde der zweite Thread womöglich wirklich hängen bleiben, falls notify wirklich schneller ausgeführt wird als wait. Das sagt scheinbar auch der erste Satz aus:
      In dem Aufwach-Beispiel stellt man sicher, dass der wartende Kontext nicht hängengelassen wird.
      Nur mit dem zweiten Satz habe ich Probleme (sofern ich ihn überhaupt richtig übersetzt habe):
      Hat man nämlich den Synchronisierung-Lock erreicht und das Objekt warten nicht, dann braucht es auch nicht zu warten.
      Was könnte das bedeuten? Das Objekt wartet doch bereits, sobald der Synchronisierungs-Lock erreicht wurde, oder?

      Kommentar


      • #4
        Ok, ich habe es verstanden.

        Den Synchronisierungs-Lock liefert synchronized. Und dieser Synschonisierungs-Lock ist unabhändig davon, ob ein Thread mittels wait gelockt oder mittels notiy freigegeben wurde.

        Alles geklärt. Danke

        Kommentar


        • #5
          Die done-Eigenschaft ist eigentlich etwas, das in einer Schleife stehen sollte und nicht in einer Bedingung, da Threads spontan aufwachen können. Dein sleep() täuscht vor, dass der Hauptthread arbeitet. Das sleep() sollte übrigens niemals benutzt werden, um auf Threadausführungen zu warten.

          Das Beispiel ist auch im Übrigen viel zu klein, daraus kann niemand schlau werden, wenn man vom wait/notify-Idiom keine Ahnung hat. Denn nimmt man das Beispiel von php.net, wird wait() niemals ausgeführt (zumindest würde es nicht in Java und C++, habe es in PHP noch nie getestet). Außerdem arbeitet der Thread gar nicht, sodass es gar keinen Sinn ergibt, diesen überhaupt zu erstellen.

          Was genau die done-Frage angeht: Das solltest du immer machen (mit der oben beschriebenen Schleife), denn du könntest auf Deadlocks stoßen. In deinem konkreten Beispiel, gibt es in Java zumindest einen Deadlock, weil das wait() nach dem notify() ausgeführt wird.


          PHP-Code:
          public class My implements Runnable {
              public 
          boolean done false;
              private 
          Object lock;
              public 
          My(Object lock) {
                  
          this.lock lock;
              }
              public 
          void run() {
                  
          synchronized (lock) {
                      
          //if (!done) {
                          
          try {
                              
          System.out.println("Wait");
                              
          lock.wait();
                          } catch (
          InterruptedException e) {}
                      
          //}
                  
          }
              }
          }


          public class 
          Main {

              public static 
          void main(String[] args) {
                  
          Object lock = new Object();
                  
          My my = new My(lock);
                  
          Thread thread = new Thread(my);
                  
          thread.start();
                  
          synchronized(lock) {
                      
          System.out.println("Done = true");
                      
          my.done true;
                      
          lock.notify();
                  }
                  try {
                      
          thread.join();
                      
          System.out.println("JOIN");
                  } catch (
          InterruptedException e) {}
              }


          Ausführung gibt (und muss wegen Deadlock terminated werden):
          Code:
          Done = true
          Wait
          Müsste in PHP eigentlich auch dasselbe sein, denn Threads werden nicht sofort nach start() gestartet, das Betriebssystem lässt sich da ein wenig Zeit.

          Ich rate dir auch übrigens an, komplett auf synchronized/wait/notify zu verzichten (vor allem in PHP, da du nicht, wie in Java, nicht irgendein Objekt synchronisieren darfst, sondern nur einen ganzen Thread). Die eigentlich immer bessere (und schnellere) Alternative sind die Mutex- und Cond-Klassen.

          /Edit: Ups, da habe ich wohl was lange gebraucht, um die Antwort zu tippen.
          Crashkurs zum Thema Rechtschreibung: [COLOR="Green"]normalerweise[/COLOR] ([COLOR="Red"]normaler weise[/COLOR] oder [COLOR="Red"]normaler weiße[/COLOR]), [COLOR="DarkGreen"]Standard[/COLOR] ([COLOR="Red"]Standart[/COLOR]), [COLOR="DarkGreen"]eben[/COLOR] ([COLOR="Red"]ebend[/COLOR])

          Kommentar

          Lädt...
          X