Penyelesaian untuk mengelakkan proses php pcntl_fork daripada mati: 1. Buka fail kod PHP yang sepadan 2. Semak kod pemprosesan php multi-thread 3. Lulus "public function installSignal(){pcntl_signal(SIGTERM, [$ This, 'sigHandle'])...};" boleh digunakan untuk memasang pemproses isyarat.
Persekitaran pengendalian tutorial ini: sistem Windows 7, PHP versi 8.1, komputer Dell G3.
Apakah yang perlu saya lakukan sekiranya proses php pcntl_fork tidak mati?
Penerangan Masalah
Kali pertama saya menggunakan PHP multi-threading untuk mengendalikan tugasan, masalah proses zombi berlaku. Sebabnya proses anak berlaku tidak menghantar isyarat tamat dan proses induk tidak menunggu Tamat proses anak
Pemahaman
pcntl_fork kembali -1: Gagal untuk memulakan proses 0: Menunjukkan bahawa proses anak semasa adalah lebih besar daripada sifar: Proses induk semasa, nilai pulangan ialah pid proses anak
Selepas kod proses anak fork dilaksanakan , ia mesti keluar() dan menghantar isyarat tamat. Jika tidak, teruskan proses anak bercabang. Dapatkan proses induk pid = posix_getppid(), pid semasa = getmypid() atau posix_getpid()
Proses induk adalah yang terbaik untuk menunggu proses anak selesai melaksanakan dan mengitar semula kanak-kanak proses melalui pcntl_wait(), pcntl_waitpid( ) untuk melaksanakan menunggu segerak dan tak segerak untuk proses induk menggelungkan proses anak:
$result = pcntl_waitpid($pid_, $status, WNOHANG); $result等于-1时代表子进程结束
Fungsi pemproses isyarat adalah untuk memproses isyarat tamat yang dikembalikan oleh proses kanak-kanak
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']); }
Pembelajaran yang disyorkan: "Tutorial Video PHP"
Atas ialah kandungan terperinci Apakah yang perlu saya lakukan jika proses php pcntl_fork tidak mati?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!