调用pcntl_fork两次会导致 PHP CGI 死循环


function spawn($exec, $args = array()) {
$pid = pcntl_fork();
if ($pid < 0)
    return false;
else if ($pid == 0) {
    $ppid = getmypid();
    $pid = pcntl_fork();
    if ($pid < 0)
        file_put_contents('/tmp/error.log', "fork failed: ${cmd} ". implode(' ', $args). "n");
    else if ($pid == 0) {
        pcntl_waitpid($ppid, $status);
        pcntl_exec($exec, $args);
    }
    else
        exit(0);
    }
}

这在 CLI 模式下效果很好。但是对于php-fpm,它会导致调用者死循环,然后超时。为什么会这样?

不起作用,因为在 FPM 下调用exit()不会导致父进程退出 - 它只是让它清理请求,然后返回到可用工作进程池。由于它从未真正退出,因此pcntl_waitpid最终会永远等待。

正如 Roman Newaza 所指出的,您应该真正避免在 FPM 下(以及通常,在 CLI 之外(下使用pcntl函数。

不应在 Web 服务器环境中

启用进程控制,如果在 Web 服务器环境中使用任何进程控制功能,则可能会发生意外结果: PCNTL/简介

最新更新