PHP Conference Japan 2024

简介

PHP 中的进程控制支持实现了 Unix 风格的进程创建、程序执行、信号处理和进程终止。不应在 Web 服务器环境中启用进程控制,如果在 Web 服务器环境中使用任何进程控制函数,可能会出现意外结果。

本文档旨在解释每个进程控制函数的一般用法。有关 Unix 进程控制的详细信息,建议您查阅系统文档,包括 fork(2)、waitpid(2) 和 signal(2),或参考全面的参考书籍,例如 W. Richard Stevens 编著的《UNIX 环境高级编程》(Addison-Wesley)。

PCNTL 现在使用滴答作为信号处理回调机制,这比以前的机制快得多。此更改遵循与使用“用户滴答”相同的语义。您使用 declare() 语句来指定程序中允许发生回调的位置。这使您可以最大程度地减少处理异步事件的开销。过去,使用启用 pcntl 的 PHP 进行编译始终会产生此开销,无论您的脚本是否实际使用 pcntl。

注意此扩展在 Windows 平台上不可用。

添加注释

用户贡献的注释 3 条注释

49
sean dot kelly at mediatile dot com
12 年前
以下语句让我搜索了大约一天的答案,然后我终于明白了

"不应在 Web 服务器环境中启用进程控制,如果在 Web 服务器环境中使用任何进程控制函数,可能会出现意外结果。"

至少对于我正在使用的 PHP 5.3.8 以及谁知道多久以前,它不是“不应”的问题,而是“不能”。即使我已经使用 --enable-pcntl 编译了 PCNTL,但事实证明它只编译到 PHP 的 CLI 版本中,而不是 Apache 模块中。因此,我花了几个小时试图找出为什么 function_exists('pcntl_fork') 返回 false,即使它编译正确。事实证明,它从 CLI 中返回 true 非常好,并且仅对 HTTP 请求返回 false。所有 pcntl_*() 函数都是如此。
5
InvisibleSmiley
4 年前
pcntl 函数的禁用不仅影响 Apache 服务器,还影响任何非 CLI 设置,例如带有 PHP-FPM 的 nginx。

您可以通过发出 phpinfo() 并查看输出的“核心”部分中的“disable_functions”来判断。

还值得注意的是,当您在命名空间上下文中调用 pcntl 函数之一时,此行为可能会非常具有误导性。例如,您可能会得到

"调用未定义函数 some\custom\namespace\pcntl_signal()"

当从命名空间类中的方法调用 pcntl_signal 时。您的第一直觉可能是添加一个前导反斜杠,但这并不能解决问题。您需要在运行时检查该函数是否存在,除非代码仅在 CLI 中执行。
12
Rick Sustek
8 年前
实际上,为什么在 Apache 模块中不支持进程控制功能是完全有道理的。Apache HTTP 服务器是主进程。当通过请求的资源(例如 http://foo.php)引导到 PHP 时,它会调用 PHP 模块。它调用 PHP 模块,通常是在新线程或池化线程上。然后 PHP 模块运行您的脚本,但 Apache 服务器仍然是拥有进程。

在此执行模型中,PHP 脚本的工作通常是尽快完成其工作并返回。这允许 Apache 守护进程对它借给您的线程做一些其他有用的事情。是的,有些脚本执行其职责所需的时间比其他脚本长,但通常不赞成长时间阻塞线程。

如果允许您的脚本弄乱正在运行的进程的信号处理程序,那么它将弄乱 Apache 守护进程本身!该守护进程已经安装了用于自身使用的信号处理程序。在这种情况下,不允许进程控制操作是完全合理的。
To Top