ホームページ  >  記事  >  バックエンド開発  >  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, [$これ、'sigHandle'])...};" を使用してシグナル プロセッサをインストールできます。

php pcntl_fork プロセスが停止しない場合はどうすればよいですか?

このチュートリアルの動作環境: Windows 7 システム、PHP バージョン 8.1、Dell G3 コンピューター。

php pcntl_fork プロセスが停止しない場合はどうすればよいですか?

問題の説明

PHP マルチスレッド処理タスクを初めて使用したときに、ゾンビ プロセスの問題が発生しました。その理由は、子プロセスが送信を行わなかったことです。終了シグナルと親プロセスは待機しませんでした。子プロセスの終了

理解

  • pcntl_fork は -1 を返します: 開始に失敗しましたプロセス 0: 現在の子プロセスが 0 より大きいことを示します: 現在の親プロセス、戻り値は子プロセスです。 pid

  • fork 子プロセス コードが実行されると、 exit() を実行して終了シグナルを送信する必要があります。それ以外の場合は、子プロセスのフォークを続行します。親プロセスを取得します。 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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。