php pcntl_fork進程不死掉的解決辦法:1、開啟對應的PHP程式碼檔案;2、查看php多執行緒處理程式碼;3、透過「public function installSignal(){pcntl_signal(SIGTERM, [$ this, 'sigHandle'])...};”方式安裝訊號處理器即可。
本教學操作環境:windows7系統、PHP8.1版、Dell G3電腦。
php pcntl_fork 進程不死掉怎麼辦?
問題描述
第一次使用php多執行緒處理任務引起殭屍進程問題,原因是子進程沒有發送結束訊號,父進程沒有等待子程序的結束
理解
pcntl_fork 返回-1:開啟進程失敗0:表示目前是子進程大於零:目前是父進程,回傳值是子進程pid
fork的子進程程式碼執行完後必須exit(),發送結束訊號。否則繼續fork子進程。取得父行程pid = posix_getppid(), 當前pid = getmypid()或posix_getpid()
父程式最好等待子程序執行結束回收子程序透過pcntl_wait()、pcntl_waitpid( )實作同步、非同步等待父行程循環子程序:
$result = pcntl_waitpid($pid_, $status, WNOHANG); $result等于-1时代表子进程结束
#訊號處理器的作用是根據處理子程序傳回的結束訊號進行處理
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']); }
推薦學習:《PHP影片教學》
以上是php pcntl_fork 進程不死掉怎麼辦的詳細內容。更多資訊請關注PHP中文網其他相關文章!