Préparation
Nous savons tous que PHP s'exécute en un seul processus. La gestion de la multi-concurrence par PHP repose principalement sur le multi-processus du serveur ou PHP-FPM et du serveur. réutilisation de leurs processus, mais PHP L'implémentation de plusieurs processus est également d'une grande importance, en particulier lors du traitement de grandes quantités de données ou de l'exécution de processus démons DEMON
en arrière-plan en mode Cli en arrière-plan.
Le multi-threading de PHP a également été mentionné, mais le problème du partage et de l'allocation des ressources multi-thread au sein du processus est difficile à résoudre. PHP possède également une extension multi-thread pthreads
, mais elle est dite instable et nécessite que l'environnement soit thread-safe, elle n'est donc pas beaucoup utilisée.
Dans le passé, un grand maître du groupe PHP a dit un jour que si PHP en arrière-plan veut progresser, il doit éviter le multi-processus. Il se trouve que le processus démon de l'entreprise utilise également le multi-processus de PHP. processus, combiné avec les différents de Gu Ge Après avoir lu les informations et les manuels, j'ai enfin compris le multi-traitement et écrit une petite démo (implémentée sur un système Linux, je la résumerai dans cet article). S'il y a des erreurs ou des omissions, merci. vous de les avoir mentionnés.
Pour implémenter le multi-traitement en PHP, nous avons besoin de deux extensions pcntl
et posix
La méthode d'installation ne sera pas décrite ici.
En php, nous utilisons pcntl_fork()
pour créer plusieurs processus (dans la programmation en langage C des systèmes *NIX, les processus existants génèrent de nouveaux processus en appelant la fonction fork). Le nouveau processus après le fork devient le processus enfant, le processus d'origine devient le processus parent et le processus enfant possède une copie du processus parent. Notez ici :
• Le processus enfant partage le segment de texte du programme avec le processus parent
• Le processus enfant a une copie de l'espace de données, du tas et de la pile du processus parent. Notez que c'est le cas. une copie, pas un partage
• Le processus parent et le processus enfant continueront à exécuter le code du programme après le fork
• Après le fork, que le processus parent ou le processus enfant s'exécute d'abord ne peut pas être confirmé, et cela dépend de la planification du système (dépend de la croyance)
Il est dit ici que le processus enfant a une copie de l'espace de données, du tas et de la pile du processus parent. dans la plupart des implémentations, il ne s'agit pas d'une véritable copie complète. Plus important encore, la technologie COW (Copy On Write) est utilisée pour économiser de l'espace de stockage. Pour faire simple, si ni le processus parent ni le processus enfant ne modifient ces données, ce tas et cette pile, alors le processus parent et le processus enfant partagent temporairement les mêmes données, tas et pile. Ce n'est que lorsque le processus parent ou le processus enfant tente de modifier les données, le tas et la pile qu'une opération de copie se produit. C'est ce qu'on appelle la copie sur écriture.
Après avoir appelé pcntl_fork(), la fonction renverra deux valeurs. Renvoie l'ID de processus du processus enfant dans le processus parent et renvoie le numéro 0 à l'intérieur du processus enfant lui-même. Étant donné que plusieurs processus ne peuvent pas s'exécuter correctement dans l'environnement Apache ou FPM, vous devez exécuter le code dans l'environnement php cli.
Créer un sous-processus
La création d'un sous-processus PHP est le début de plusieurs processus, nous avons besoin de la fonction pcntl_fork()
explication détaillée de la fonction fork
— Générer une branche (processus enfant) à la position actuelle du processus actuel. Une fois que cette fonction a créé un nouveau processus enfant, le processus enfant héritera du contexte actuel du processus parent et continuera à s'exécuter vers le bas depuis la fonction pcntl_fork()
comme le processus parent, sauf que la valeur de retour de pcntl_fork()
obtenue est différente, nous pouvons donc distinguer le processus parent et le processus enfant en jugeant la valeur de retour, et le processus parent et le processus enfant peuvent être affectés à des traitements logiques différents. pcntl_fork()
instance de processus fork
processus enfant fork
$ppid = posix_getpid(); $pid = pcntl_fork(); if ($pid == -1) { throw new Exception('fork child process fail'); } elseif ($pid > 0) { cli_set_process_title("我是父 process,pid is : {$ppid}."); sleep(30); } else { $cpid = posix_getpid(); cli_set_process_title("我是 {$ppid} 子的 process,我的 process pid is : {$cpid}."); sleep(30); }
Description :
posix_getpid() : renvoie l'identifiant du processus actuelcli_set_process_title('process name') : donne un nom fort au processus actuel. En exécutant cet exemple, nous pouvons voir les deux processus PHP actuels.www@iZ2zec3dge6rwz2uw4tveuZ:~/test$ ps aux|grep -v grep |grep 我 www 18026 0.5 1.2 204068 25772 pts/0 S+ 14:08 0:00 我是父 process,pid is : 18026. www 18027 0.0 0.3 204068 6640 pts/0 S+ 14:08 0:00 我 18026 子的 process,我的 process pid is : 18027.
$pid = pcntl_fork(); if( $pid > 0 ){ echo "我是父亲".PHP_EOL; } else if( 0 == $pid ) { echo "我是儿子".PHP_EOL; } else { echo "fork失败".PHP_EOL; }
www@iZ2zec3dge6rwz2uw4tveuZ:~/test$ php 123.php 我是父亲 我是儿子
// 初始化一个 number变量 数值为1 $number = 1; $pid = pcntl_fork(); if ($pid > 0) { $number += 1; echo "我是父亲,number+1 : { $number }" . PHP_EOL; } else if (0 == $pid) { $number += 2; echo "我是儿子,number+2 : { $number }" . PHP_EOL; } else { echo "fork失败" . PHP_EOL; }
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!