Maison  >  Article  >  développement back-end  >  Que dois-je faire si le processus php pcntl_fork ne s'arrête pas ?

Que dois-je faire si le processus php pcntl_fork ne s'arrête pas ?

藏色散人
藏色散人original
2022-10-25 09:14:541384parcourir

Solution pour empêcher le processus php pcntl_fork de mourir : 1. Ouvrez le fichier de code PHP correspondant ; 2. Affichez le code de traitement multi-thread php ; 3. Passez "public function installSignal(){pcntl_signal(SIGTERM, [$this, 'sigHandle '])...};" méthode pour installer le processeur de signal.

Que dois-je faire si le processus php pcntl_fork ne s'arrête pas ?

L'environnement d'exploitation de ce tutoriel : système Windows 7, PHP version 8.1, ordinateur Dell G3.

php pcntl_fork Que dois-je faire si le processus ne s'arrête pas ?

Description du problème

La première fois que j'ai utilisé le multi-threading php pour traiter des tâches, le problème du processus zombie a été provoqué. La raison était que le processus enfant n'avait pas envoyé de signal de fin et que le processus parent n'avait pas attendu. la fin du processus enfant

Comprendre

  • pcntl_fork Retour -1 : Échec du démarrage du processus. 0 : Indique que le processus enfant actuel est supérieur à zéro : il s'agit actuellement du processus parent. le processus enfant pid

  • fork. Une fois le code du processus enfant exécuté, il doit quitter () et envoyer un signal de fin. Sinon, continuez à bifurquer le processus enfant. Obtenez le processus parent pid = posix_getppid(), current pid = getmypid() ou posix_getpid()

  • Le processus parent est préférable d'attendre que le processus enfant termine son exécution et de recycler le processus enfant pour obtenir une attente synchrone et asynchrone. le processus parent via pcntl_wait() et pcntl_waitpid() Sous-processus de boucle :

$result = pcntl_waitpid($pid_, $status, WNOHANG);
 
$result等于-1时代表子进程结束
  • La fonction du processeur de signal est de traiter le signal final renvoyé par le sous-processus de traitement

public function run()
    {
        $this->installSignal();
        // 获取当前pid   getmypid()
        $current_pid = posix_getpid();
        // dump('当前pid:'.$current_pid);
        cli_set_process_title('设置process_title');
        $pids = [];
        for($i = 0; $i < $this->forks; $i ++){
            $pid = pcntl_fork();
            if($pid == -1){
                die(&#39;进程开启失败&#39;);
            }else if($pid){
                // 父进程得到子进程pid
                dump(&#39;父进程&#39;);
                dump(&#39;父进程得到子进程pid&#39;.$pid);
                $pids[] = $pid;
            }else{
                dump(&#39;子进程&#39;);
                dump(&#39;父进程pid-&#39;.posix_getppid());
                // 子进程
                dump("第{$i}个进程");
                sleep(10);
                dump("第{$i}个进程:等待10s");
                // 发送结束信号
                // exit(-1);
                // posix_kill(getmypid(), SIGKILL);
                posix_kill(getmypid(), SIGHUP);
            }
        }
        // 父进程等待子进程执行结束
        while($pids){
            foreach($pids as $k => $pid_){
                dump(&#39;父进程不阻塞-等待子进程结束&#39;);
                $result = pcntl_waitpid($pid_, $status, WNOHANG);
                dump($result);
                if($result === -1){
              dump(&#39;子进程返回状态&#39;.$status);
       unset($pids[$k]);
                }
        }
    }
    /**
     * 信号处理器
     */
    public function sigHandle($signo)
    {
        switch ($signo) {
            case SIGTERM:
                // 处理SIGTERM信号
                dump(&#39;处理SIGTERM信号&#39;);
                exit;
                break;
            case SIGHUP:
                    //处理SIGHUP信号
                dump(&#39;处理SIGHUP信号&#39;);
                exit(SIGHUP);
                break;
            case SIGUSR1:
                dump(&#39;处理SIGUSR1信号&#39;);
                break;
            default:
                // 处理所有其他信号
        }
    }
    /**
     * 安装信号处理器
     *
     */
    public function installSignal()
    {
        pcntl_signal(SIGTERM, [$this, &#39;sigHandle&#39;]);
        pcntl_signal(SIGHUP, [$this,&#39;sigHandle&#39;]);
        pcntl_signal(SIGUSR1, [$this,&#39;sigHandle&#39;]);
    }

Apprentissage recommandé : "Tutoriel vidéo PHP"

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