Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP:pcntl_fork()真正做什么?_Php_Apache_Thread Safety_Fork_Process Control - Fatal编程技术网

PHP:pcntl_fork()真正做什么?

PHP:pcntl_fork()真正做什么?,php,apache,thread-safety,fork,process-control,Php,Apache,Thread Safety,Fork,Process Control,PHP的pcntl_fork函数应该像C中的标准fork函数一样fork一个进程。 但是我想知道这个函数是否真的分叉了这个过程,或者它是否以不同的方式模拟了这个行为。 如果它真的分岔了进程,那么很清楚哪个进程是Apache的子进程。 只要Apache使用prefork MPM(即,每个请求一个进程),就可以了。 但是,如果Apache正在使用worker MPM,会发生什么呢?? 在使用worker MPM时,每个Apache子进程都包含许多线程,每个线程处理不同的HTTP请求。因此,如果您在这

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


专家们怎么说?我的推理是否正确,或者我只是在胡说八道?

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

是的,这应该是一个分叉过程。甚至声明您应该阅读
manfork(2)
以获得进一步的说明,因此它可能只是C fork函数的包装

更新:以下是适用于worker MPM的PHP手册中的相关页面:

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

我还找到了这一页,其中包含一些进一步的说明: 可能按照您的想法工作:它分叉当前进程,与C函数分叉的方式相同:

函数的作用是创建一个 不同于 父进程仅在其PID和 PPID
请查看您系统的
fork(2)
手册页,了解具体信息 有关fork如何在您的计算机上工作的详细信息 系统。


但是,引用手册的一节:

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

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


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

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


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

我会尽量快速简洁

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

另一方面,我已经在很多项目中使用了forking,它在优化大多数项目方面非常出色,但是,在apache中滥用forking时存在一个bug,我基本上是在给forking的孩子提供forking,做任何类型的硬核工作,它都可以工作。。。很好,但是在负载下,它在开始创建僵尸进程之前工作了一段时间,我可以使用“pcntl_signal(SIGCHLD,SIG_IGN);”来管理僵尸进程,这基本上会在孩子完成任务后立即删除进程,这会有一点帮助,然后当apache变得疯狂时,开始执行线程并最终崩溃您的服务器,我无法解释这种行为(目前,但我会解释)apache创建的weir/evil树只能从“ps”中看到,也不能从服务器状态或apache日志中看到,我说evil树是因为它基本上创建了数百个带有子进程的进程

简言之:

使用apache的Fork可以工作吗?对绝对

只是不要滥用它


希望这将对某些人有所帮助

“web服务器环境中不应启用流程控制”=>必须记住始终阅读介绍@帕斯卡尔马汀?该评论是什么意思?相关材料可在《阅读公认答案》中有关过程控制的章节中找到,尤其是我对该答案的评论。
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