Le blog de Dju - DéveloppementUn peu de moto, un zeste de geek, et un brin d'autres trucs ;-)2024-03-22T17:50:26+01:00Djuurn:md5:5e61426dd704534f4aef077f5b82260bDotclearMultithread en php sous debianurn:md5:9aed831a9342c07dc9ded95b0950ee4f2010-05-19T22:45:00+02:002010-11-04T20:06:10+01:00DjuDéveloppementdebianmultithreadpcntlphp<p><img src="https://blog.crifo.org/public/201003/.php_t.jpg" alt="php.jpg" style="float:left; margin: 0 1em 1em 0;" title="php.jpg, mar. 2010" />
On peut faire plein de choses avec php, meme des processus multi-threads.<br />
Mais ce n'est pas faisable d'origine car les fonctions "pcntl_" ne sont pas activées.<br />
Voici comment faire</p> <p><br />
<br />
On commence par installer php-dev</p>
<blockquote><p>aptitude install php5-dev</p></blockquote>
<p>puis on aura besoin des sources de php5</p>
<blockquote><p>mkdir php5<br />
cd php5<br />
apt-get source php5</p></blockquote>
<p>on se déplace alors dans le repertoire des fonctions pcntl et on compile les extensions<br />
(Au besoin, afin de pouvoir compiler, il faudra installer le paquet build-essential)</p>
<blockquote><p>cd php5/ext/pcntl<br />
phpize<br />
./configure<br />
make</p></blockquote>
<p>maintenant, on copie les modules dans le repertoire de php (le nom du dernier repertoire peut changer suivant votre version de php)</p>
<blockquote><p>cp modules/* /usr/lib/php5/20060613+lfs/</p></blockquote>
<p>enfin, on active l'extension dans le php.ini (par defaut, <strong>/etc/php5/apache/php.ini</strong> ou bien <strong>/etc/php5/cli/php.ini</strong> pour la version ligne de commande)<br />
On y rajoute la ligne</p>
<blockquote><p>extension=pcntl.so</p></blockquote>
<p>si c'est la version apache, ne pas oublier de relancer apache</p>
<blockquote><p>/etc/init.d/apache2 restart</p></blockquote>
<p>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 :</p>
<pre>
<?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;
}
}
?>
</pre>
<p>ici, on déclare un nombre maximum de 16 threads, dont 5 simultanés.<br />
Amusez vous bien <img src="/themes/BlueSky/smilies/wink.gif" alt=";)" class="smiley" /></p>
<p><ins>EDIT AU 04/11/2010 :</ins><br />
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....<br />
En cherchant un peu et testant diverses solutions, en voici une qui fonctionne bien.<br />
JE reprend l'exemple du dessus, mais en adaptant avec cette autre technique :</p>
<pre>
<?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 );
}
}
?>
</pre>
<p>ici, on va vérifier combien de threads executant le script /dossier/script.php tournent.<br />
On rend l'exécution asynchrone grâce à '> /dev/null &' placé à la fin.<br />
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 &</p>https://blog.crifo.org/post/2010/05/19/Multithread-en-php-sous-debian#comment-formhttps://blog.crifo.org/feed/atom/comments/51