Le multithreading en PHP est absent "
prêt à l' emploi", donc de nombreuses options ont été inventées pour sa mise en œuvre, y compris les extensions
pthreads ,
AzaThread (CThread), et même certains des développements des développeurs PHP.
Le principal inconvénient pour moi était trop de «cloches et de sifflets» pour ces solutions - il n'y a pas toujours un besoin d'échange d'informations entre les threads et le processus parent ou d'économiser des ressources. Il devrait toujours être possible de résoudre le problème rapidement et à moindre coût.
Je veux faire une réservation à l'avance pour que de grands secrets n'ouvrent pas dans cet article - c'est plus probable pour les débutants dans la langue, et j'ai décidé de le publier uniquement parce que j'avais rencontré un problème moi-même et, n'ayant pas trouvé de solution toute faite, j'ai fait moi-même une sorte d'émulation multithreading.
La tâche consiste donc à traiter une grande quantité de données qui sont entrées dans notre script. Ma tâche consistait à traiter un tableau JSON d'informations textuelles, digérant que le script devait en collecter un commit tout aussi important pour PostgreSQL.
Tout d'abord, nous collectons les données dans le fichier parent:
index.php
La taille du tableau a fluctué autour de 400 Mo (plus tard, elle a été réduite à environ 50 Mo), et toutes les informations étaient textuelles. Il n'est pas difficile d'estimer la vitesse à laquelle tout a été digéré, et étant donné que le script était exécuté sur cron toutes les 15 minutes, et la puissance de calcul était telle - les performances ont beaucoup souffert.
Après avoir reçu les données, vous pouvez estimer leur volume et, si nécessaire, calculer le nombre nécessaire de threads pour chaque cœur de processeur, ou vous pouvez simplement décider qu'il y aura 4 threads et calculer le nombre de lignes pour chaque thread:
index.php
Il convient de le mentionner tout de suite - un tel calcul «frontal» ne donnera pas un résultat exact en fonction du nombre d'éléments pour chaque flux. Il est plus nécessaire de simplifier les calculs.
Et maintenant l'essence même - nous créons des tâches pour chaque thread et l'exécutons. Nous ferons ce «front» - en créant une tâche pour le deuxième fichier - thread.php. Il agira comme un "flux", recevant une gamme d'éléments pour le traitement et le démarrage indépendamment du script principal:
index.php
La fonction
passthru () est utilisée pour exécuter les commandes de la console, mais le script attendra que chacune d'elles se termine. Pour ce faire, nous enveloppons la commande de lancement dans un ensemble d'instructions qui démarrera le processus et ne renverra immédiatement rien, démarrant le processus et le processus parent n'arrêtera pas d'attendre que chaque enfant s'exécute:
Ce qui se passe exactement ici, malheureusement, je ne peux pas le dire avec certitude - un ensemble de paramètres m'a été suggéré par mon familier Linuxoid. Si vous pouvez déchiffrer cette magie dans les commentaires, je vous en serai reconnaissant et compléterai le message.
Fichier thread.php:
$start = $argv[1]; $stop = $argv[2]; for ($i = $start; $i <= $stop; $i++) {
De cette façon, assez simple, vous pouvez implémenter l'émulation multithreading en PHP.
Si nous réduisons l'exemple entier à une sortie sèche, je pense que cela ressemblerait à ceci: le thread parent via la ligne de commande lance des processus enfants, leur indiquant les informations à traiter.
Quand je dis «émulation», je veux dire qu'avec cette méthode d'implémentation, il n'y a aucun moyen d'échanger des informations entre les threads ou entre les threads parent et enfant. Il convient si l'on sait à l'avance que de telles fonctionnalités ne sont pas nécessaires.