php.de

Zurück   php.de > Webentwicklung > PHP-Fortgeschrittene

PHP-Fortgeschrittene Arbeiten mit PHP ohne Einschränkungen

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 18.07.2009, 00:10  
Erfahrener Benutzer
 
Registriert seit: 17.07.2009
Beiträge: 223
PHP-Kenntnisse:
Fortgeschritten
Tiberius zeigte ein beschämendes Verhalten in der Vergangenheit
Tiberius eine Nachricht über ICQ schicken
Standard Emulierte "Threads" per IPC

Hallo zusammen,

mein erster Beitrag hier im Forum und dann auch noch bei den Fortgeschrittenen, bin schon ein wenig aufgeregt!

Also, mir geht es um das Thema Threads in PHP welche nun mal leider nicht vorhanden sind. Dafür gibt es die Möglichkeit Prozesse zu starten, stoppen und zu steuern. Somit kann man Threads in gewisser Weise emulieren.

Vor ein paar Wochen hab ich mit der Umsetzung begonnen und mich an den Java - Threads orientiert. Nun möchte ich allen, die das Thema interessiert, die entstandenen Möglichkeiten aus der bisherigen Entwicklung aufzeigen.

Leider ist mir kein guter Name dafür eingefallen, daher nenn ich die Klasse vorerst Thread. Es handelt sich um eine abstrakte Klasse die immer vererbt werden muss, eine instanzierbare Form ist im Moment nicht möglich. Vielleicht fällt mir dafür noch eine Lösung ein.

Auflistung der interessantesten Methoden(aktueller Stand)
- isAlive()
- join($milliseconds)
- start()
- stop()
- resume()
- destroy()
- setDaemon()
- suspend($milliseconds)
- isSuspended()
- sleep()
- dumpStack()
- get/setPriority() [nur mit pcntl]
- call()
- execute()
- wait($var, $timeout = 0)
- waitForUpdate($var, $timeout = 0)


Kurzer Überblick
- Die erbende Klasse muss eine run Methode enthalten
- Scalare, Arrays und Objekte werden vom Hauptprozess in den "Thread" Prozess gespiegelt
- Änderungen in Objekten und Arrays werden ebenfalls gespiegelt
- per "setDaemon()" kann ein Thread unbegrenzt lange laufen und auf Aufgaben zur Abarbeitung warten, solange mindestens ein Thread besteht beendet sich der Hauptprozess nicht
- "call" ruft eine Methode samt Argumenten im Thread auf und liefert das Ergebnis zurück
- "execute()" ist wie call(), nur wird nicht auf die Rückkehr gewartet
- "wait()" lässt den Hauptprozess auf eine Variable im Thread warten und gibt den Wert aus
- "waitForUpdate()" lässt den Hauptprozess warten bis sich der Wert einer Variablen im Thread ändert

Die Mankos liegen auf der Hand
- Resources können nicht gehandhabt werden
- Redundante Datenhaltung aufgrund getrennter Prozesse

Beispiel
PHP-Code:
    class Runnable extends Thread
    
{
        public function 
run()
        {
            
console::println('run');

            for(
$i 0$i 10; ++$i)
            {
                
console::println($i);
                
thread::sleep(500);
            }
        }
    }


    final class 
Test
    
{
        public static function 
main(array $argv$argc)
        {
            
$r1 = new Runnable('pthread 1');
            
$r1->start();

            
$r2 = new Runnable('pthread 2');
            
$r2->start();
            
$r2->suspend(6000);

            
$r3 = new Runnable('pthread 3');
            
$r3->start();
            
            
#$r1->join();
            
$r2->join();
            
#$r3->join();

            
console::println('Im Main - Thread');
        }
    } 
Code:
Pfad...>php53 main.php
[17.07.2009 23:37:06] thread::pthread 1~: run
[17.07.2009 23:37:06] thread::pthread 1~: 0
[17.07.2009 23:37:06] thread::pthread 1~: 1
[17.07.2009 23:37:07] thread::pthread 1~: 2
[17.07.2009 23:37:07] thread::pthread 1~: 3
[17.07.2009 23:37:07] thread::pthread 2~: run
[17.07.2009 23:37:07] thread::pthread 2~: 0
[17.07.2009 23:37:08] thread::pthread 1~: 4
[17.07.2009 23:37:08] thread::pthread 1~: 5
[17.07.2009 23:37:09] thread::pthread 1~: 6
[17.07.2009 23:37:09] thread::pthread 1~: 7
[17.07.2009 23:37:09] thread::pthread 3~: run
[17.07.2009 23:37:09] thread::pthread 3~: 0
[17.07.2009 23:37:10] thread::pthread 3~: 1
[17.07.2009 23:37:10] thread::pthread 1~: 8
[17.07.2009 23:37:10] thread::pthread 1~: 9
[17.07.2009 23:37:10] thread::pthread 3~: 2
[17.07.2009 23:37:11] thread::pthread 3~: 3
[17.07.2009 23:37:11] parent~: shutdown initiated
[17.07.2009 23:37:11] thread::pthread 3~: 4
[17.07.2009 23:37:12] thread::pthread 3~: 5
[17.07.2009 23:37:12] thread::pthread 3~: 6
[17.07.2009 23:37:13] thread::pthread 2~: 1
[17.07.2009 23:37:13] thread::pthread 3~: 7
[17.07.2009 23:37:13] thread::pthread 2~: 2
[17.07.2009 23:37:13] thread::pthread 3~: 8
[17.07.2009 23:37:14] parent~: thread pthread 1 - shutdown complete
[17.07.2009 23:37:14] thread::pthread 2~: 3
[17.07.2009 23:37:14] thread::pthread 3~: 9
[17.07.2009 23:37:14] thread::pthread 2~: 4
[17.07.2009 23:37:14] parent~: shutdown initiated
[17.07.2009 23:37:15] thread::pthread 2~: 5
[17.07.2009 23:37:15] thread::pthread 2~: 6
[17.07.2009 23:37:16] thread::pthread 2~: 7
[17.07.2009 23:37:16] thread::pthread 2~: 8
[17.07.2009 23:37:17] parent~: thread pthread 3 - shutdown complete
[17.07.2009 23:37:17] thread::pthread 2~: 9
[17.07.2009 23:37:17] parent~: Im Main - Thread
[17.07.2009 23:37:17] parent~: shutdown initiated
[17.07.2009 23:37:20] parent~: thread pthread 2 - shutdown complete
[17.07.2009 23:37:20] parent~: shutdown complete
Analyse der Ausgabe
* Thread 1 startet und schafft 4 Ausgaben vor dem Start von Thread 2
* Thread 2 macht eine Ausgabe, dann wird es vom suspend(6000) für 6 Sekunden schlafen gelegt.
* Thread 1 + 3 laufen durch, der Hauptprozess beendet sich nicht
* Durch $r2->join(); wird gewartet bis auch Thread 2 am Ende ist

Meine Fragen nun an euch, was haltet ihr von der ganzen Sache, für wen ist es interessant?¿?

Das ganze soll in ein paar Wochen OpenSource gehen. Mir schwebt da code.google oder sourceforge vor. Kann jemand einen von beiden empfehlen oder kennt ne andere gute Plattform? Im Moment tendiere ich zu google. Allerdings kommen vorher noch ein paar Erweiterungen hinzu, ThreadGroups und ThreadJobs aber das ist ein anderes Thema für später

Achja, und ich suche noch einen guten Namen dafür, es sind Prozesse die wie Threads gehandhabt werden, vielleicht fällt euch was ein - bin für alles offen, Namensgebung, Diskussionen und Anregungen/Kritik/Erweiterung der Methoden!
Tiberius ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 18.07.2009, 14:34  
Erfahrener Benutzer
 
Registriert seit: 16.07.2005
Beiträge: 1.007
PHP-Kenntnisse:
Fortgeschritten
brian johnson befindet sich auf einem aufstrebenden Ast
Standard

imo geht das an der idee des threads vorbei, ein Thread ist eben nur ein teil eines prozesses. interessant wird das erst, wenn der Kritische Abschnitt erreicht wird. ab da benötigst du synchrone verarbeitung, ansonsten kommt das programm zu falschen ergebnissen.
außerdem ist das langsam ohne ende, denn für einen prozesswechsel muss der Kernel eine menge arbeit verrichten. schön sieht man die nachteile von Threademlurierung durch Prozesse bei der veralteten LinuxThread lib die mittlerweile von Native POSIX Thread Library abgelöst wurde:

Zitat:
Im August/September 2002 wurde der Linux-Kernel 2.5 für die NPTL vorbereitet. Dazu war es notwendig, einige neue Systemaufrufe einzuführen und vorhandene zu optimieren. In ersten Benchmarks konnten nun auf einem IA-32-System innerhalb von 2 Sekunden 100.000 parallele Threads erzeugt werden; ohne NPTL dauerte allein die Erzeugung der Threads fast 15 Minuten. Trotz dieser bemerkenswerten Last blieb das System während dieser Tests annähernd mit normaler Geschwindigkeit benutzbar.
schlussendlich gehe ich davon aus, das du PCNTL benutzt, oder? wenn ja, so solltest du den ersten abschnitt beachten:

Zitat:
Process Control support in PHP implements the Unix style of process creation, program execution, signal handling and process termination. Process Control should not be enabled within a web server environment and unexpected results may happen if any Process Control functions are used within a web server environment.
__________________
PHP4?!?>>>Aktuelle PHP Version: 5.2.11 || 5.3.0
Suse 11.2 *vorfreude*
brian johnson ist offline   Mit Zitat antworten
Alt 19.07.2009, 14:28  
Erfahrener Benutzer
 
Registriert seit: 17.07.2009
Beiträge: 223
PHP-Kenntnisse:
Fortgeschritten
Tiberius zeigte ein beschämendes Verhalten in der Vergangenheit
Tiberius eine Nachricht über ICQ schicken
Standard

Nein ich setze nicht auf PCNTL, es bietet zu wenig Möglichkeiten um einen Prozess in diesen Feinheiten zu steuern, zumal es so gut wie nur auf unix verfügbar ist. Lediglich die Methoden get-/setPriority() nutzen pcntl sofern auf dem System vorhanden.

Per proc_open() wird ein Prozess gestartet, über die Pipes kommuniziert. Dies ist unter win und unix möglich. Durch ticks kann zwischen dem normalen Ablauf über die Pipes kommuniziert werden. Das BS muss sich nicht um das Handling der Prozesse kümmern, diese pausieren, stoppen, starten oder fortlaufen lassen. Das passiert im Programmablauf. Zugegeben unter Vista stirbt die Maschine bei der Prozesserstellung nahezu (vielleicht mal wieder nen Boot, der tut bekanntlich immer gut ^^), unter XP gehts recht flott und unix liegt im Millisekundenbereich.

Das Thema Synchronisierung ist NOCH nicht aktuell, wird aber kommen wenn der Hauptprozess Zugriffe von seine Unterprozessen zulässt.

Wie geschrieben, es sind keine Threads sondern Prozesse. Die Handhabung der Prozesskommunikation orientiert sich an der Java-Thread API. Mir fiel bisher nur kein besserer Begriff/Name ein.

In erster Linie ist diese Entwicklung aufs CLI SAPI ausgerichtet, da ich es dafür benötige. Ich gehe aufgrund des ticks momentan nicht davon aus, dass es im Apache oder einem sonstigen Webserver läuft.
Tiberius ist offline   Mit Zitat antworten
Alt 19.07.2009, 15:35  
erc
Erfahrener Benutzer
 
Registriert seit: 02.01.2009
Beiträge: 730
PHP-Kenntnisse:
Fortgeschritten
erc wird schon bald berühmt werden
Standard

Erst heiß machen und dann hängen lassen... tztz Mich würde der Code schon interessieren. Vorallendingen wie erreichst du es das du direkt in einer Instanz einsteigen kannst? Oder interpetiere ich den Code zuviel rein?

PHP-Code:
    class Runnable extends Thread
    
{
    private 
$counter 10;
    
    public function 
setCounter($counter) {
        
$this->counter $counter;
    }
    
        public function 
run()
        {
            
console::println('run');

            for(
$i 0$i $this->counter; ++$i)
            {
                
console::println($i);
                
thread::sleep(500);
            }
        }
    }

    
    
$test = new Runnable('foo');
    
$test->setCounter(100);
    
$test->run(); 
Aber ok beim schreiben sind mir auch ein paar Ideen dazu eingefallen, aber ob die praktisch so umsetzbar sind...
erc ist offline   Mit Zitat antworten
Alt 19.07.2009, 18:13  
Erfahrener Benutzer
 
Registriert seit: 17.07.2009
Beiträge: 223
PHP-Kenntnisse:
Fortgeschritten
Tiberius zeigte ein beschämendes Verhalten in der Vergangenheit
Tiberius eine Nachricht über ICQ schicken
Standard

Her mit den Ideen!

"5.3.0 Ticks are now supported on threaded web server modules." klingt gut, dann wird es auch in Apache(Worker?) & Co. laufen.

Welche Instanz meinst du gerade, die public static function main inTest? Dafür hab ich ein Runtime Objekt welches automatisch diese besagte main Methode sucht.

Die run() Methode der Instanz wird nicht direkt aufgerufen, sondern per start(). Im Moment entsteht der neue Prozess allerdings erst mit dem Aufruf von start(). Denke das werd ich morgen ändern. Mit der Instanz würde dann der Prozess gestartet, gehalten und wie auch immer über start() oder execute('run') angestossen werden.

Um eine Eigenschaft zu setzen/ändern kann man eine Methode direkt aufrufen. Dann muss die Eigenschaft allerdings von der Instanz an den Prozess übergeben werden(implizit). Der elegantere Weg wäre die Methode direkt anzuweisen(explizit)

Dein Beispiel funktioniert(implizit), so ist es ebenfalls möglich(explizit)
PHP-Code:
   ...

    
$test = new Runnable('foo');
    
$test->execute('setCounter'100);
    
$test->start(); 
Damit ruft die Instanz die Methode setCounter samt dem Parameter '100' direkt im Unterprozess auf
Tiberius ist offline   Mit Zitat antworten
Antwort


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
php pthread, pthread set thread sleep, \start thread\ php4, \threaded web server modules\, php ipc pcntl, pthreads ausgaben console, thread ipc

Alle Zeitangaben in WEZ +2. Es ist jetzt 00:45 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum