Multi-threading en PHP : vers une solution ? (MAJ)
Par -Alexandre LEGOUT aka LAlex- le 15 juin 2004, 10:01 - PHP - Lien permanent
PHP a beau être un langage qui n'a pas à rougir de la comparaison avec les "gros" langages tels que Java, il lui manque néamoins quelques fonctionnalités avancées qui simplifieraient la vie du codeur, et éventuellement pourraient améliorer les performances de manières significative.
Parmi ces fonctionallités "manquantes", le multi-threading est probablement la plus importante à mon sens. Sur les plateforme de type UNIX, il est possible de dupliquer un processus grace à l'utilisation de l'extension PCNTL et son instruction pcntl_fork(), mais pas de créer plusieurs threads. Pour information, le thread est la plus petite entité en terme d'instruction processeurs. Les différents threads d'un processus sont répartis en terme de traitement par le processeur afin de simuler leurs executions simultanées.
Vraisemblablement, le problème a déjà commencé à être abordé par des codeurs du PHP Group, et ce depuis un bon moment. PHP5 ne gérant pas nativement le multi-threading, il s'agit donc d'une extension PECL. Pour rappel, PECL est un sytème d'extensions la plupart du temps codées en C/C++, et compilées à la manière des extensions "natives" de PHP (MySQL, Oracle, Sockets : celles que l'on active dans le php.ini). On trouve ainsi dans la liste de ces extensions de quoi gérer le format zip, ou se connecter à un serveur POP3...
Pour les experts en C/C++ qui veulent éventuellement y toucher, ou développer leurs propres extensions natives, vous trouverez sur le site de PECL les instructions nécessaires à un tel codage.
Attention à ne pas confondre ces possibilités d'extension avec les extensions PEAR, qui elles sont codées en PHP. Pour les flasheurs, ca correspond à la différence entre les classes fournies avec Flash, codées en AS, et les classes "intrinsic", natives au Player Flash. En PHP, il est possible d'en rajouter étant donné que tout se passe sur le serveur ! ![]()
Pour revenir à nos moutons, on trouve dans le repository CVS du PHP Group, une extension en cours de développement nommée php_threads ... que l'on retrouve dans les extensions PECL des Snapshots PHP que ce soit pour la branche stable (4.3.x) ou la branche instable (5.0.x), compilée sous forme de dll pour Windows. N'étant pas expert de l'utilisation des threads, je ne me suis pas encore risqué à l'utiliser, mais pour ceux qui s'y connaissent déjà, voici les fonctions que l'on retrouve dans la source en C de l'extension :
- thread_start
- thread_include
- thread_set
- thread_get
- thread_mutex_init
- thread_mutex_destroy
- thread_lock
- thread_lock_try
- thread_unlock
Affaire à suivre donc !
MAJ : J'ai trouvé sur le web une autre initiative pour l'implémentation des Threads en PHP, dont la syntaxe me plait beaucoup plus. Elle est faite pour coller complètement à la syntaxe Java, avec une approche Objet. Il suffit pour créer un thread de dériver la classe Thread justement ... Les sources sont disponibles au téléchargement, mais aucune version compilée à priori, ni aucune page dédiée, ou doc. A voir l'exemple, c'est quand-même beaucoup plus convivial qu'un ensemble de fonctions. N'étant qu'un début d'essai de prémice, ce module a de grandes chances d'être hautement instable (lire le README). A utiliser avec précautions donc ! ![]()
A voir les sources, l'API du Zend Engine semble vraiment assez accessible, et pour un développeur trés calé, il ne devrait pas être si difficile que ca de finir le travail entamé je pense (faudrait que je me remette au C/C++ moi :P). Il n'y a pas de volontaires ? Ce serait le bonheur de pouvoir avoir une implémentation stable des threads ... ^^
Commentaires
yeah cool !!
mais c'et marrant dernierement tu avais parlé de serveur socket en php... ben je pensé que le threading etait forcement lié a cette pratique... apparemment pas...
effectivement je me posais la même question, comment sont géré les socket de chaque client puisqu'il n'y pas de Thread?
Dans le serveur, il s'agit tout simplement d'un boucle infinie qui écoute chaque socket client. Les sockets non-bloquants permettent de n'obtenir que les sockets qui ont emis un message (ou accepté une nouvelle connexion pour ce qui est du socket "serveur"), et donc de n'effectuer les traitements que sur ceux-là ....
Du coup, on est pas loin des performances du multi-threading en réception, mais dans l'autre sens, pour envoyer un message, on les envoie l'un aprés l'autre .... :?
Ca ressemble fort au C non ?
je viens de jeter un oeil au pat server et ... je comprends pas trop snif... ce que tu appelles des socket non bloquant... c'est des socket UDP ? sinon il fait pour arriver "pas loin des perf de multithreading" puisque le traitement et fait par le meme process... enfin ca derive peut etre trop du sujet, la...
Ce qui est sur c'est qu'on pourra faire un vrai serveur de chaussette si la lib marche bienbien, avec a chaque demande de connection, la creation d'un thread.. yeah, comme les vrais serveurs!
yoy > C'est la version PEAR (ou ma version en PHP5) qu'il faut regarder : ca passe par l'utilisation de socket_select ...
++ ^^
Salut
Des threads en PHP, pourquoi pas, mais en tant que pratiquant régulier je ne vois pas trop l'interet pour un usage web. Disons que je n'en ai jamais eu besoin, mais je reste ouvert.
Est ce que JSP, ASP, CF et les autres ont des threads?
Cédric
Sauf que les vrais serveurs ont pas un thread par connexion, enfin apache par exemple gere plusieurs connexions par thread, sinon la surcharge dûe au thread acheve la machine.
Cédric > PHP n'a pas qu'un usage web ...
Et même dans le cadre d'un usage web, imagine un agrégateur de feed RSS, ne serait-il pas pratique de pouvoir en récupérer plusieurs à la fois en terme de performances ? 
Sinon, JSP peut utiliser les threads, comme ASP.NET (ASP tout court, chuis pas sûr :$)
++ ^^
que veux-tu dire par un "vrai" serveur, tous les serveurs socket que je connais (a par celui en php
euh, Apache n'est pas un serveur socket
Pour ce qui est des serveur HTTP, Apache Tomcat lui par contre démarre un Thread pour chaque requete client, ce qui a pour but de ne pas démarrer un nouveau process pour chaque requête.
Je vais revoir Apache, mais il me semble bien dans la conf que chaque thread gere plusieurs connexions, tout simplement parce qu'aucun OS n'est capable de gérer autant de thread qu'un serveur accepte de connexions. Donc je suppose qu'il n'est pas le seul.
Sinon pour la récup via le réseau oui les threads on un interet. Ok.
Ah si, plus que jamais !

Sais tu qu'en dérivant la classe du serveur PHP tu peux faire un serveur Web ? Un serveur HTTP n'est ni plus ni moins qu'un serveur de socket qui interprète des requêtes HTTP et répond en conséquence ...
oui sur qu'il y a des socket, mais la connexion se ferme aussitôt que le traitement de la requête est terminé. Je parle d'un serveur socket persistant en tcp/ip ou udp, et non http...
euh ... udp chui pas sur ... puisque c'est pas un mode connecté... enfin il me semble
la connexion en UDP n'est pas persistante, mais le serveur qui gère ces connexions l'est...
j'ai déjà fait un serveur UDP pour un jeu en .NET, et j'ai utiliser des Thread...
hihi... oui evidement le serveur est persistant... sinon il ecouterait pas grand chose
meaculpa
Malheureusement, les diverses extensions basées sur pthread pour PHP ne fonctionnent pas encore. On ne peut utiliser que pcntl, qui ne fonctionne qu'avec CLI ou CGI.
De toutes façons, un script qui nécessite du multithreading ou multiprocessing devrait tourner avec CLI ou CGI, et non pas en tant que module.
Le problème c'est que PHP est mal considéré. Tout le monde pense que ce n'est qu'un petit langage pour faire des pages webs dynamiques... Mais non, PHP est un vrai langage de script tout comme Tcl ou Perl.
C'est pour ça que j'ai beaucoup de difficultés à trouver des hebergeurs avec PHP en CLI (shell) ou en CGI (hebergement web) avec l'extension pcntl.
Si quelqu'un en connaitrait un, ce serait sympa de me l'indiquer.
Salut, le probleme avec l'extension pcntl à mon avis c'est qu'elle peut mettre à genoux ton serveur.
Heuresement de nos jours ils tendent à n'être que virtuels
Fil des commentaires de ce billet