Multithread en php sous debian
Par Dju » 19 mai 2010 (22:45) - Développement
On peut faire plein de choses avec php, meme des processus multi-threads.
Mais ce n'est pas faisable d'origine car les fonctions "pcntl_" ne sont pas activées.
Voici comment faire
On commence par installer php-dev
aptitude install php5-dev
puis on aura besoin des sources de php5
mkdir php5
cd php5
apt-get source php5
on se déplace alors dans le repertoire des fonctions pcntl et on compile les extensions
(Au besoin, afin de pouvoir compiler, il faudra installer le paquet build-essential)
cd php5/ext/pcntl
phpize
./configure
make
maintenant, on copie les modules dans le repertoire de php (le nom du dernier repertoire peut changer suivant votre version de php)
cp modules/* /usr/lib/php5/20060613+lfs/
enfin, on active l'extension dans le php.ini (par defaut, /etc/php5/apache/php.ini ou bien /etc/php5/cli/php.ini pour la version ligne de commande)
On y rajoute la ligne
extension=pcntl.so
si c'est la version apache, ne pas oublier de relancer apache
/etc/init.d/apache2 restart
and voila, on peut maintenant s'amuser avec le multi-threading, dont voici un script d'exemple très simple pour montrer comment l'utiliser :
<?php declare(ticks = 1); $childs_nb = 16; $childs_simult = 5; $child=0; function sig_handler($signo) { global $child; switch ($signo) { case SIGCHLD: $child -= 1; } } # fonction pour signaler un enfant qui meurt pcntl_signal(SIGCHLD, "sig_handler"); for ($i=1;$i<=$childs_nb;$i++) { # création d'un processus enfant $child++; $pid = pcntl_fork(); # si impossible de forker if ($pid == -1) { die("could not fork"); } # processus pere else if ($pid) { # si plus de 5enfants simultannés, pause if ( $child >= $childs_simult ){ pcntl_wait($status); $child++; } } # un nouvel enfant est né else { echo "$i est né\n"; # l'enfant travaille sleep(3); # l'enfant a vécu et meurt echo "$i meurt !\n"; exit; } } ?>
ici, on déclare un nombre maximum de 16 threads, dont 5 simultanés.
Amusez vous bien
EDIT AU 04/11/2010 :
J'ai du récemment mettre en place du multithread en php, mais pour des raisons de restriction, les fonctions pcntl_* étaient désactivées....
En cherchant un peu et testant diverses solutions, en voici une qui fonctionne bien.
JE reprend l'exemple du dessus, mais en adaptant avec cette autre technique :
<?php $childs_nb = 16; $childs_simult = 5; $cmd_child = 'php5 -f /dossier/script.php > /dev/null &'; $cmd_test_childrens = "ps aux | grep -v grep | grep '/dossier/script\\.php' | wc -l"; for( $a=0; $a<$childs_nb; $a++ { $current_childrens = exec( $cmd_test_childrens ); if( $current_childrens < $childs_simult ) { exec( $cmd ); } else { sleep( 3 ); } } ?>
ici, on va vérifier combien de threads executant le script /dossier/script.php tournent.
On rend l'exécution asynchrone grâce à '> /dev/null &' placé à la fin.
Attention, la redirection vers /dev/null est très importante.
Sans elle, la fonction exec() attendra que le script soit fini, et vous rendra la main seulement après et pas immédiatement, malgré le &
Tu confonds multi-threading (qui n'est malheureusement juste pas possible en PHP) et muti-process.
Un thread n'est pas un processus.
pengu> c'est absolument vrai, ce n'est pas du multi-threads mais du multi-process. c'est juste une "facilité" de langage.
pour me faire pardonner, je vais aller m'auto-fouetter de ta part
Au lieu de mettre '> /dev/null &' tu aurais pu utiliser la commande 'nohup' tel que:
'nohup php5 -f /dossier/script.php&'
(cela permet aussi d'avoir le script qui continue de s'exécuter meme s'il est lancé à partir de la ligne de commande et que tu fermes ta session). Cela enregistre aussi dans un fichier le résultat de la commande.
Fil des commentaires de ce billet
URL de rétrolien : https://blog.crifo.org/trackback/51