Concurrence et multithreading en PHP : de la théorie à la pratique

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Concurrence et multithreading en PHP : approches modernes



PHP est traditionnellement associé à l'exécution synchrone de code. Cependant, les applications web modernes nécessitent le traitement de plusieurs tâches simultanément : du téléchargement de fichiers à l'analyse de grandes données. Dans cet article, nous allons voir comment implémenter la concurrence et le multithreading en PHP, en utilisant des outils intégrés et tiers.



Qu'est-ce que la concurrence et le multithreading ?



La concurrence est la capacité d'un programme à exécuter plusieurs tâches « simultanément » en basculant entre elles. Le multithreading est un cas particulier de concurrence où les tâches sont exécutées dans des threads séparés du système d'exploitation.



Dans PHP avant la version 7.4, il n'y avait pas de support natif des threads. Cependant, avec l'apparition des extensions pthreads et parallel, ainsi que l'amélioration du travail avec les processus, la situation a changé.



1. Multithreading avec l'extension parallel



L'extension parallel est une méthode moderne pour travailler avec les threads en PHP 7.4+. Elle utilise la mémoire partagée, ce qui permet d'échanger efficacement des données entre les threads.



Installation :

pecl install parallel


Exemple de création d'un thread :

<?phpuse parallel\\Runtime;

$runtime = new Runtime();$future = $runtime->run(function() { // Calculs lourds $result = 0; for ($i = 0; $i < 1000000; $i++) { $result += sqrt($i); } return $result;});

echo "Le thread principal continue son travail...";$result = $future->value(); // Récupération du résultatecho "Résultat : $result";?>


Avantages de parallel :

  • Support natif des threads sans dépendances superflues
  • Mémoire partagée entre les threads
  • Possibilité de transmettre des closures et des objets


Inconvénients :

  • Nécessite PHP 7.4+ et ZTS (Zend Thread Safety)
  • Non supporté sur Windows
  • Difficultés de débogage


2. Asynchronisme via les processus : pcntl_fork



Si vous n'avez pas besoin de mémoire partagée, vous pouvez utiliser les processus avec pcntl_fork(). C'est une approche Unix classique.



<?php$pid = pcntl_fork();

if ($pid == -1) { die("Erreur de création du processus");} elseif ($pid) { // Processus parent echo "Parent : attente du processus enfant..."; pcntl_wait($status); echo "Parent : processus enfant terminé";} else { // Processus enfant echo "Enfant : exécution de la tâche..."; sleep(3); exit(0);}?>


Caractéristiques du travail avec les processus :

  • Chaque processus a sa propre mémoire
  • Pour échanger des données, utilisez les sockets, la mémoire partagée (shmop) ou les fichiers
  • Il faut gérer les processus zombies avec pcntl_wait()


3. Concurrence via les fonctions asynchrones et ReactPHP



Pour les tâches d'entrée-sortie (requêtes réseau, lecture de fichiers), il est plus efficace d'utiliser des bibliothèques asynchrones comme ReactPHP ou Amp. Elles ne créent pas de threads, mais permettent d'exécuter des tâches de manière concurrente via une event loop.



Exemple avec ReactPHP :

<?phprequire 'vendor/autoload.php';

use React\\EventLoop\\Factory;use React\\Http\\Browser;

$loop = Factory::create();$client = new Browser($loop);

$promises = [];$urls = [ 'https://api.example.com/data1', 'https://api.example.com/data2', 'https://api.example.com/data3'];

foreach ($urls as $url) { $promises[] = $client->get($url);}

// Attente de toutes les requêtes en parallèle$results = [];foreach ($promises as $promise) { $results[] = $promise->wait();}

$loop->run();print_r($results);?>

Blogs

Book Recommendations