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.
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('进程开启失败'); }else if($pid){ // 父进程得到子进程pid dump('父进程'); dump('父进程得到子进程pid'.$pid); $pids[] = $pid; }else{ dump('子进程'); dump('父进程pid-'.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('父进程不阻塞-等待子进程结束'); $result = pcntl_waitpid($pid_, $status, WNOHANG); dump($result); if($result === -1){ dump('子进程返回状态'.$status); unset($pids[$k]); } } } /** * 信号处理器 */ public function sigHandle($signo) { switch ($signo) { case SIGTERM: // 处理SIGTERM信号 dump('处理SIGTERM信号'); exit; break; case SIGHUP: //处理SIGHUP信号 dump('处理SIGHUP信号'); exit(SIGHUP); break; case SIGUSR1: dump('处理SIGUSR1信号'); break; default: // 处理所有其他信号 } } /** * 安装信号处理器 * */ public function installSignal() { pcntl_signal(SIGTERM, [$this, 'sigHandle']); pcntl_signal(SIGHUP, [$this,'sigHandle']); pcntl_signal(SIGUSR1, [$this,'sigHandle']); }
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!