Maison  >  Article  >  développement back-end  >  Introduction détaillée à pcntl_fork dans php multi-processus

Introduction détaillée à pcntl_fork dans php multi-processus

黄舟
黄舟original
2017-10-16 09:19:132032parcourir

Cet article présente principalement des informations pertinentes sur l'exemple détaillé de pcntl_fork compilé par PHP multi-processus. J'espère que cet article pourra aider tout le monde à comprendre et à maîtriser cette partie du contenu. Les amis dans le besoin pourront s'y référer

Explication détaillée de l'exemple de pcntl_fork dans la programmation multi-processus PHP

En fait, PHP prend en charge la concurrence, mais il est rarement utilisé. La méthode la plus couramment utilisée consiste à utiliser PHP-FMP pour planifier le processus php.

Cependant, l'utilisation de PHP ne se limite pas au Web. Nous pouvons également utiliser PHP pour la programmation, la surveillance ou l'exploitation et la maintenance des outils système. En utilisant ces instructions, nous pouvons utiliser davantage de fonctionnalités de PHP, telles que la concurrence (multi-processus), la programmation socket, etc.

Parlons ensuite de la programmation multi-processus PHP que j'ai rencontrée. Il existe un historique de l'utilisation de ce multi-processus. Le contexte est vaguement décrit ci-dessous.

J'ai besoin d'un système de surveillance. Bien sûr, j'utilise le langage PHP. Le système de surveillance doit surveiller de nombreux types d'indicateurs du système. Afin de permettre à chaque indicateur de surveillance de se concentrer sur ses propres tâches, il doit le faire. utilisez un processus distinct. Pour surveiller un indicateur, il existe également un processus pour lire la configuration. Après avoir obtenu la configuration, démarrez chaque processus en fonction de la configuration.

Ensuite, cela nécessite ce que j'appelle du multi-processus.

  1. Démarrez d'abord un processus principal, qui est utilisé pour lire les informations de configuration. Par exemple, j'ai lu que je dois surveiller 5 indicateurs

  2. Ensuite, le processus principal démarre 5 sous-processus pour surveiller ces 5 indicateurs respectivement.

  3. Après avoir créé 5 processus de surveillance des indicateurs, le processus principal effectue la configuration de la surveillance.

  4. Une fois la configuration modifiée, tuez le processus précédent et recréez le processus.


Logique relativement claire. Alors simplifions le fonctionnement : pour faire simple, un processus principal crée 5 sous-processus.

Tout d'abord, pour créer un processus, vous devez utiliser une fonction pcntl_fork() en PHP. Certains étudiants ne sont peut-être pas familiers avec cette fonction, mais toute personne ayant été exposée à la programmation Linux C le sait. est une fonction appelée fork() sous Linux, utilisée pour créer des processus enfants. Cette fonction a la même signification que cette fonction sous Linux. A noter que cette fonction n'est utilisable que sous Linux, et que l'extension pcntl doit être installée.

Pour savoir comment utiliser cette fonction, nous pouvons consulter le document officiel : http://php.net/manual/zh/function.pcntl-fork.php

L'officiel Le document ressemble à ceci :

La fonction pcntl_fork() crée un processus enfant. Ce processus enfant n'est différent de son processus parent qu'en PID (numéro de processus) et PPID (numéro de processus parent). Pour plus de détails sur le fonctionnement de fork sur votre système, consultez le manuel fork(2) de votre système.

En cas de succès, le PID du processus enfant généré est renvoyé dans le thread d'exécution du processus parent et 0 est renvoyé dans le thread d'exécution du processus enfant. En cas d'échec, -1 est renvoyé dans le contexte du processus parent, le processus enfant n'est pas créé et une erreur PHP est générée.

De cette façon, un processus enfant peut être créé. Une fois le processus enfant créé avec succès, la méthode après pcntl_fork() sera exécutée. Alors, comment comprendre la valeur de retour de cette fonction ?

C'est le cas. Lorsque nous appelons une fonction pour créer un processus, il y a un moment où la fonction est exécutée, et le nouveau processus est créé juste entre le début et la fin de l'exécution de la fonction. , le nouveau processus est également exécuté. Cette fonction est requise, la fonction doit donc également avoir une valeur de retour. Ensuite, une fois la fonction exécutée une fois, le processus parent et le processus enfant recevront la valeur de retour de la fonction. Puisque le processus parent crée le processus enfant, mais que le processus enfant ne crée pas de nouveau processus, le processus enfant n'a pas de nouveau processus. renvoie le résultat de cette fonction, il a donc reçu un 0. Le processus parent crée un processus enfant, et le processus enfant a un pid, donc le pid de ce processus est obtenu.

Nous pouvons écrire un programme pour le savoir :


$pid = pcntl_fork();
var_dump($pid);
Cet appel produira deux valeurs, mais si nous l'imprimons directement, nous ne pouvons que voir Une valeur est le pid du processus enfant, mais en utilisant var_dump, nous pouvons voir deux valeurs, qui sont 0 et le pid du processus enfant. La valeur 0 est renvoyée par le processus enfant.

Après avoir compris comment créer un processus, nous pouvons commencer à créer des processus. Nous devons créer 5 processus, je vais donc boucler 5 fois pour créer des processus. Obtenez le code suivant :


 $i=0;
 while($i!=5){
  $pid = pcntl_fork();
  echo $pid."---------hahah".$i++.PHP_EOL;
 }
C'est tout. Exécutons-le. ah ? J'ai trouvé qu'il n'y avait pas 5 processus. J'ai trouvé qu'il y avait beaucoup de processus, et la dernière sortie de hahah4 était 32. Pourquoi était-ce 32 ? Faisons le calcul. 2^5=32, pourquoi le nombre final de threads a-t-il augmenté de façon exponentielle ?

Ce n'est pas difficile à trouver, car chacun d'entre nous exécute ensuite une boucle while, et à la fin cela devient une croissance exponentielle du processus - c'est-à-dire que la boucle while est également introduite en fourchant. Mais nous n’avons besoin que de 5 processus. Ce qu'il faut faire?

D'après les recherches précédentes sur la fonction, nous pouvons voir que le processus enfant renverra une valeur de 0, nous pouvons donc savoir que 0 est la marque du processus enfant. Nous pouvons terminer l'exécution du processus en marquant le processus enfant. Nous pouvons donc modifier notre code sous la forme suivante :


$i=0;
while($i!=5){
 $pid = pcntl_fork();
 echo $pid."---------hahah".$i++.PHP_EOL;
 if ($pid == 0) {
  echo "子进程".PHP_EOL;
  return;
 }
}

因为0其实是对子进程的标记,那么pid这个变量在子进程里实际上是0的,所以当发现pid的值为0的时候,我们就可以断定我们当前进程为一个子进程,不需要在让他执行while并创建子进程的子进程了,所以在执行完我们的内容之后就return或者exit退出这个执行就好了。这样就能保证我们执行创建了5个进程而不是32个了。

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn