PHP 的 pcntl_fork 函数应该像 C 中的标准 fork 函数一样 fork 一个进程。
但我想知道这个函数是否真的分叉了该过程,或者它是否以不同的方式模拟了该行为。
如果它确实分叉了该进程,那么很清楚哪个进程是:Apache 的子进程之一。
只要 Apache 使用 prefork MPM(即每个请求一个进程)。
但是如果 Apache 使用工作 MPM 会发生什么?
当使用工作 MPM 时,每个 Apache 子进程都包含许多线程,每个线程处理不同的 HTTP 请求。因此,如果您在这种情况下分叉进程,我什至无法想象所有这些线程和正在服务的请求会发生什么。
因此,如果 pcntl_fork() 确实分叉了该进程,那么我认为如果您将 Apache 设置为使用工作 MPM,那么使用此函数并不是一个好主意。

专家怎么说?我到底是在胡说八道,还是在胡说八道呢?

有帮助吗?

解决方案

pcntl_fork 可能会像你想象的那样工作:它分叉当前进程,与 C 函数 fork 的方式相同:

pcntl_fork() 函数创建一个 子进程不同于 父进程仅在其 PID 中和 PPID的。
请查看您的系统 fork(2) 特定手册页 关于分叉如何在你的 系统。


但是,引用 过程控制简介 手册部分:

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

因此,您实际上不应该在通过 Apache 执行的 PHP 脚本中使用该函数:仅当从命令行执行 PHP 脚本时才应使用它。


并且,在开始使用该功能之前,不要忘记:

笔记:此扩展不可用 在 Windows 平台上。

其他提示

首先,在为工作 MPM 配置的 Apache 安装上将 PHP 作为模块运行并不是一个好主意,因为 PHP 不是线程安全的(我认为 PHP 手册中也有说明)。

它应该分叉这个过程,是的。这 PHP手册 甚至指出你应该阅读 man fork(2) 以获得更多说明,因此它可能只是 C fork 函数的包装器。

更新:以下是 Worker MPM 的 PHP 手册中的相关页面:http://php.net/install.unix.apache2.php

笔记:要构建 Apache 的多线程版本,目标系统必须支持线程。在这种情况下,PHP 还应该使用实验性 Zend 线程安全 (ZTS) 进行构建。在此配置下,并非所有扩展都可用。推荐的设置是使用默认的 prefork MPM 模块构建 Apache。

我还发现此页面包含一些进一步的说明:http://www.stevekallestad.com/blog/apache_worker_mpm_with_php.html

我会尽量快速简洁

通过apache使用“fork”是可能的,您需要“安装”然后启用php.ini中的功能,最后您需要在apache directori中添加扩展(符号链接也可以完成工作) 前任:

echo "extension=pcntl.so" > /etc/php5/conf.d/pcntl.ini
ln -s /etc/php5/apache2/conf.d/pcntl.ini /etc/php5/mods-available/pcntl.ini 

另一方面,我一直在很多项目中使用分叉,它在优化大多数项目方面确实很棒,但是,在使用 apache 滥用它时存在一个错误,我基本上分叉了分叉的子项并执行任何类型的操作硬核的东西而且它有效......很好,但是在负载下,它在开始创建僵尸进程之前工作了一段时间,我可以使用“pcntl_signal(SIGCHLD, SIG_IGN)”来管理僵尸进程;“,这基本上会在孩子完成任务后立即删除该进程,这有点帮助,然后是 apache 发疯的时候,开始线程化,最后使你的服务器崩溃, 我无法解释这种行为(但我会)Apache 创建的这个 Weir/Evil 树只能从“ps”或 server-status 或 apache 日志中看到,我说 evil tree 是因为它基本上创建了数百个进程的孩子的孩子......

简而言之:

Fork 与 apache 可以工作吗?是的...绝对地

只是不要滥用它

希望这会对某人有所帮助

我刚刚尝试通过apache使用pcntl_fork,奇怪的情况是,在fork一个子进程后,父进程将标准输出(浏览器)提供给其子进程。因此,您可以想象,浏览器无法接收父进程的输出。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top