Thread PHP dans Copix

Publié le 27/04/2008

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 :)

comments powered by Disqus