Thread PHP dans Copix
Alors qu'on discutait sur le canal #fedora-fr de
langages, et que je défendais PHP :) on a parlé des
threads inexistants dans PHP. En fait, je savais
qu'il était possible de faire des fork
dans PHP, seulement sous Linux, et je me suis
décidé à réaliser deux classes pour gérer des
Threads dans Copix. Elles se nommeront CopixThread
et CopixThreadManager.
Ce sera commité après validation de la Copix Team,
mais rien ne m'empêche de vous présenter le travail
maintenant. En fait, j'utilise les méthodes
pcntl qui créent des fork via les
méthodes POSIX.
Voici un exmple simple. Imaginons deux classes qui, lors de leur appel, prennent environ 2 secondes pour l'une et 5 secondes pour l'autre. Si je ne me trompe pas, l'appel successif à ces méthodes vont durer 7 secondes en tout.
Or, avec un thread (ou un fork ok...) par classe, les deux méthodes vont s'exécuter en même temps. Pour cela, je passe par un manager qui va stocker les threads, attendre la fin de tous les processus, et continuer. Pourquoi passer par un manager ? Parce que à l'avenir, je devrai savoir si tous les processus se sont terminé, ne connaissant pas le temp exact qu'ils vont travailler, et que je dois aussi garder les réponses dans un coin.
Voilà donc mes deux processus sous forme de classe:
class LongProcess1 extends CopixThread{
function process(){
echo " ----- je suis la tache1 qui dort 5 secondes
";
sleep(5);
echo " ----- je suis la tache1 qui se réveille
";
}
}
class LongProcess2 extends CopixThread{
public $test = 1;
function process(){
echo " ----- je suis la tache2 qui dort 2 secondes
";
sleep(2);
echo " ----- je suis la tache2 qui se réveille
";
}
public function onFinish(){
return 12345;
}
}
Vous noterez que le second processus défini une
méthode qui retourne 12345. Cette
méthode facultative est appelée à la fin de chaque
processus. Si elle n'est pas défini, elle retourne
toujours true.
La méthode process, quant à elle, est
la méthode qui sera appelé lors de l'exécution du
thread.
Maintenant, l'appel au manager:
$manager = new CopixThreadManager();
$manager->addThread(new LongProcess1());
$manager->addThread(new LongProcess2());
$reponses = $manager->execute();
var_dump($reponses);
Le vardump final nous montrera l'état des réponses.
Reste à tester cela dans ma console. Je ne vous
impose pas d'utiliser une console, je le fais pour
utiliser la commande time qui mesurera
le temps utilisé par mes processus.
[patachou@localhost tmp]$ time php test.php
----- je suis la tache1 qui dort 5 secondes
----- je suis la tache2 qui dort 2 secondes
----- je suis la tache2 qui se réveille
----- je suis la tache1 qui se réveille
array(2) {
[0]=>
object(LongProcess1)#2 (2) {
["pid:protected"]=>
int(8959)
["result"]=>
bool(true)
}
[1]=>
object(LongProcess2)#3 (3) {
["test"]=>
int(1)
["pid:protected"]=>
int(8960)
["result"]=>
int(12345)
}
}
real 0m5.080s
user 0m0.024s
sys 0m0.030s
[patachou@localhost tmp]$
Et voilà, nous avons bien nos 5 secondes et non 7 d'exécution. On voit bien la tâche 2 se terminer avant la tâche 1. Le manager a attendu la fin des processus, et j'ai affiché mes réponses.
Vous pouvez aussi voir les "pid" (numéro de processus) assignés.
Alors pour information, le module pcntl n'est généralement pas activé dans les configurations web de PHP. Cela va sans dire que ma méthode sera utilisée plutôt dans des modules spécifiques et non dans le core de Copix. A moins que... je puisse savoir si je peux monter un processus ou non et faire marcher les processus en séquentiel et non en parallèle...
A voir donc, c'est une ébauche pour le moment :)
Pas de commentaire pour le moment
Trackbacks
Pour ajouter un trackback (retrolien) sur ce ticket, utilisez cette adresse: http://www.metal3d.org/index.php/trackback/default/tb?id=blog%2F59