>  기사  >  백엔드 개발  >  php pcntl_fork 프로세스가 종료되지 않으면 어떻게 해야 합니까?

php pcntl_fork 프로세스가 종료되지 않으면 어떻게 해야 합니까?

藏色散人
藏色散人원래의
2022-10-25 09:14:541395검색

php pcntl_fork 프로세스가 종료되는 것을 방지하는 솔루션: 1. 해당 PHP 코드 파일을 엽니다. 2. PHP 다중 스레드 처리 코드를 봅니다. 3. "public function installSignal(){pcntl_signal(SIGTERM, [$this, 'sigHandle '])...};" 신호 프로세서를 설치하는 방법입니다.

php pcntl_fork 프로세스가 종료되지 않으면 어떻게 해야 합니까?

이 튜토리얼의 운영 환경: Windows 7 시스템, PHP 버전 8.1, Dell G3 컴퓨터.

php pcntl_fork 프로세스가 죽지 않으면 어떻게 해야 하나요?

문제 설명

처음 PHP 멀티스레딩을 사용하여 작업을 처리할 때 자식 프로세스가 종료 신호를 보내지 않고 부모 프로세스가 기다리지 않아서 좀비 프로세스 문제가 발생했습니다. 하위 프로세스의 끝

Understand

  • pcntl_fork 반환 -1: 프로세스를 시작하지 못했습니다. 0: 현재 하위 프로세스가 0보다 크다는 것을 나타냅니다. 현재 반환 값은 다음과 같습니다. 하위 프로세스 pid

  • 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(&#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;]);
    }

에서 반환된 종료 신호를 처리하는 것입니다. 권장 학습: "PHP 비디오 튜토리얼"

위 내용은 php pcntl_fork 프로세스가 종료되지 않으면 어떻게 해야 합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.