× 警告!旧版文档已经暂停维护,请查看新版文档。点击前往新版文档

Process::wait

回收结束运行的子进程。

array Process::wait(bool $blocking = true);
$result = array('code' => 0, 'pid' => 15001, 'signal' => 15);
  • $blocking 参数可以指定是否阻塞等待,默认为阻塞
  • 操作成功会返回一个数组包含子进程的PID、退出状态码、被哪种信号KILL
  • 失败返回false

子进程结束必须要执行wait进行回收,否则子进程会变成僵尸进程
$blocking 仅在1.7.10以上版本可用
使用Process作为监控父进程,创建管理子进程时,父类必须注册信号SIGCHLD对退出的进程执行wait,否则子进程一旦被kill会引起父进程退出

在异步信号回调中执行wait

Process::signal(SIGCHLD, function($sig) {
  //必须为false,非阻塞模式
  while($ret =  Process::wait(false)) {
      echo "PID={$ret['pid']}\n";
  }
});
  • 信号发生时可能同时有多个子进程退出
  • 必须循环执行wait直到返回false

  • 飞酒

    如果不调用该方法,然后子进程会不会变成僵尸进程,不会自己死掉?

  • 林小军

    问个基础问题,为什么 swoole 不自动回收这部分僵尸进程

  • 万济能

    僵尸进程由于不正常的编程产生,这是开发人员的问题,操作系统无法自行处理。相当于自己的程序写出了bug,应该是这样的。

  • 广训

    注册信号 \swoole_process::signal(SIGCHLD, [$this, 'finished']);后,在finished中处理子进程: while (($result = \swoole_process::wait(false))) { $pid = $result['pid']; $exitCode = $result['code']; } 当脚本执行完毕后,一直不返回false,控制台一直等待中,直至Ctrl + C后才终止, 而要让 脚本在执行完毕后终止,使用了析构函数的方式: public function __destruct() { if (!count($this->works)) { \swoole_process::kill($this->myPid); } } 请问正确的处理应该是什么样的呢?

  • wuzhc

    僵尸进程是为了确保主进程能够正常调用wait以确定子进程终止状态,例如子进程已经结束,父进程可以在子进程结束之后的某一时刻去执行wait

  • 15093565100

    僵尸进程存在是有意义的,父进程是保留了创建的子进程pid之类的信息,如果不通过主进程回收,直接关闭掉子进程,会出现主进程的pid问题。