Maison  >  Article  >  développement back-end  >  Explication détaillée de la solution au problème du processus zombie dans PHP multi-processus

Explication détaillée de la solution au problème du processus zombie dans PHP multi-processus

黄舟
黄舟original
2017-10-16 09:11:451800parcourir

Cet article présente principalement des informations pertinentes pour comprendre le problème du processus zombie dans la programmation multi-processus PHP. J'espère que cet article pourra aider tout le monde et permettre à tout le monde de maîtriser cette partie du contenu.

Compréhension du problème du processus zombie dans la programmation multi-processus PHP

L'utilisation de la fonction pcntl_fork peut permettre à PHP d'obtenir l'effet de concurrence multi-processus ou de traitement asynchrone : http:// www.jb51.net/article/ 125789.htm

Ensuite, le problème est que le processus que nous générons doit être contrôlé et ne peut être ignoré. Le moyen le plus simple consiste à bifurquer le processus et à le tuer.

En utilisant la fonction pcntl_fork, nous avons déjà un nouveau sous-processus, et le sous-processus terminera alors ce que nous devons traiter, appelons-le donc service() pour le moment, et nous avons besoin many service() Pour le traitement, reportez-vous à nos exigences précédentes. Le processus parent doit lire le fichier de configuration en boucle et attendre que le fichier change. Par pcntl_fork, nous pouvons facilement écrire le code suivant :


$res = config();
//kill进程
for($i = 0; $i < $res[sum]; $i++) {
  $pid = pcntl_fork();
  if ($pid == 0) {
    service();
    return;
  }
}

Nous devons supprimer les zones commentées dans le code lorsque des modifications sont apportées au fichier de configuration. Processus mort. . La façon de tuer un processus est très simple. Vous pouvez utiliser la commande kill pour le tuer directement. Par exemple (en supposant que le pid soit 123) :


1 kill 123

. Mais nous avons constaté que l'utilisation de cette méthode de suppression du processus ne tue pas réellement le processus. Une fois le processus enfant tué, il occupe toujours les ressources de ce processus. Nous devenons un processus zombie qui ne peut pas être tué à l'aide de la commande kill. . Il n’y a que deux manières de résoudre ce problème.

1. arrêt

2. Tuez le processus parent du processus.

Mais aucune de ces méthodes ne fonctionnera, car le but de ce programme est de surveiller et de résider sur le serveur, le serveur ne peut pas être arrêté et le processus parent ne peut pas être tué. À ce moment-là, nous avons vu l'explication du document officiel sur la méthode fork :


pcntl_wait($status); //等待子进程中断,防止子进程成为僵尸进程。

Il s'avère qu'il existe un moyen d'empêcher le processus de devenir un processus zombie, mais le code donné sur le site officiel est Il ressemble à ceci :


$pid = pcntl_fork();
//父进程和子进程都会执行下面代码
if ($pid == -1) {
  //错误处理:创建子进程失败时返回-1.
   die(&#39;could not fork&#39;);
} else if ($pid) {
   //父进程会得到子进程号,所以这里是父进程执行的逻辑
   pcntl_wait($status); //等待子进程中断,防止子进程成为僵尸进程。
} else {
   //子进程得到的$pid为0, 所以这里是子进程执行的逻辑。
}

Qu'est-ce que cela signifie ? Autrement dit, le processus parent attendra que le processus enfant s'exécute. Une fois l'exécution du processus enfant terminée, il passera à l'étape suivante et le processus zombie sera également éliminé. Mais cela ne répond pas à nos besoins.Notre sous-processus est un programme en boucle infinie, recherchant constamment une sortie, et la mise à jour n'est pas terminée, et ce dont nous avons besoin est un traitement asynchrone plutôt qu'une synchronisation. Mais cette méthode peut-elle être utilisée ? En fait, bien sûr, vous le pouvez.

Cette fonction est expliquée dans la documentation pcntl_wait :

La fonction wait supprime l'exécution du processus en cours jusqu'à ce qu'un processus enfant se termine ou reçoive un signal demandant d'interrompre le processus en cours ou d'appeler un signal fonction de traitement. Si un processus enfant s'est terminé lorsque cette fonction est appelée (communément appelé processus zombie), cette fonction est renvoyée immédiatement. Toutes les ressources système utilisées par le processus enfant seront libérées. Veuillez consulter le manuel wait(2) de votre système pour obtenir des spécifications détaillées sur le fonctionnement de wait sur votre système.

Nous avons constaté que lorsque cette fonction découvre que le processus enfant est devenu un processus zombie, elle libère les ressources du processus zombie - à condition que le processus zombie soit un processus enfant du processus parent. Ensuite, nous pouvons intelligemment utiliser cette méthode pour laisser ces processus zombies libérer des ressources, nous avons donc le code suivant :


 posix_kill(123, 9);
 pcntl_wait($status);

De cette façon, nous utilisons d'abord kill pour tuer ce processus, ce processus ne s'exécutera plus, mais ce processus est devenu un processus zombie, occupant des ressources. Dans la phrase suivante, nous exécuterons pcntl_wait() pour permettre à ces processus zombies de libérer des ressources. terminé et le zombie Le processus est éliminé.

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