PHP:pcntl_fork() 到底做了什么?
PHP 的 pcntl_fork 函数应该像 C 中的标准 fork 函数一样 fork 一个进程。
但我想知道这个函数是否真的分叉了该进程,或者它是否以不同的方式模拟了该行为。
如果它确实分叉了该进程,那么很清楚哪个进程是:Apache 的子进程之一。
只要 Apache 使用 prefork MPM(即每个请求一个进程)就可以了。
但是如果 Apache 使用工作 MPM 会发生什么?
当使用工作 MPM 时,每个 Apache 子进程都包含许多线程,每个线程处理不同的 HTTP 请求。因此,如果您在这种情况下分叉进程,我什至无法想象所有这些线程和正在服务的请求会发生什么。
因此,如果 pcntl_fork() 确实分叉了该进程,那么我认为如果您将 Apache 设置为使用工作 MPM,那么使用此函数并不是一个好主意。
专家怎么说?我到底是在胡说八道,还是说得有理有据呢?
PHP's pcntl_fork function is supposed to fork a process just as the standard fork function in C.
But I was wondering if this function really forks the process or if it emulates that behavior in a different way.
If it really forks the process then it's clear which process that is: one of Apache's child processes.
That's OK as long as Apache is using the prefork MPM (i.e. one process per request).
But what does happen if Apache is using the worker MPM??
When the worker MPM is being used, every Apache child process contains many threads, each one handling a different HTTP request. So if you would fork the process under that situation I can't even think what would happend to all those threads and requests being served.
So if pcntl_fork() really forks the process then I think it's not a good idea to use this function if you set Apache to use the worker MPM.
What do the experts say? Am I reasoning well, or I'm just speaking nonsense?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
pcntl_fork
可能会像您想象的那样工作:它以相同的方式分叉当前进程C 函数 fork 的作用是:但是,引用手册的流程控制简介部分:
因此,您实际上不应该在通过 Apache 执行的 PHP 脚本中使用该函数:它应该仅在从命令行执行 PHP 脚本时使用。
并且,在开始使用该功能之前,不要忘记:
pcntl_fork
probably works as you think it would : it forks the current process, the same way the C function fork does :But, quoting the Introduction of the Process Control section of the manual :
So, you should not actually use that function from a PHP script executed via Apache : it should only be used when your PHP script is executed from the command-line.
And, before starting to use that function, don't forget that :
首先,在为工作 MPM 配置的 Apache 安装上将 PHP 作为模块运行并不是一个好主意,因为 PHP 不是线程安全的(我认为 PHP 手册中也有说明)。
它应该分叉这个过程,是的。 PHP 手册甚至指出您应该阅读
man fork(2)
以获取更多说明,所以它可能只是 C fork 函数的包装器。更新:以下是 Worker MPM 的 PHP 手册中的相关页面:
http://php.net/install.unix.apache2.php
我还发现此页面包含一些进一步的说明:
http://www.stevekallestad.com/blog/apache_worker_mpm_with_php.html
It's not a good idea to run PHP as a module on an Apache installation configured for worker MPM in the first place, because PHP is not threadsafe (I think that is stated somewhere in the PHP manual too).
It should fork the process, yes. The PHP manual even states that you should read
man fork(2)
for further instructions, so it's probably just a wrapper around the C fork function.Update: Here's the relevant page in the PHP manual for worker MPM:
http://php.net/install.unix.apache2.php
I also found this page with some further instructions:
http://www.stevekallestad.com/blog/apache_worker_mpm_with_php.html
我会尽量快速简洁,
通过 apache 使用“fork”是可能的,您需要“安装”然后启用 php.ini 中的功能,最后您需要在 apache 目录中添加扩展(符号链接也会完成工作)
例如:
另一方面,我一直在很多项目中使用分叉,它在优化大多数项目方面确实很棒,但是,在使用 apache 滥用它时存在一个错误,我基本上分叉了分叉的子项并执行任何类型的硬核东西,它都可以工作......非常好,但是在负载下,它可以在开始创建僵尸进程之前工作一段时间,我可以使用“pcntl_signal(SIGCHLD,SIG_IGN);”来管理僵尸进程。这基本上会在孩子完成任务后立即删除该进程,这有点帮助,然后是当 apache 变得疯狂,并开始线程本身并最终崩溃你的服务器时,我无法解释这种行为(但我会)这棵由 apache 创建的堰/邪恶树只能从“ps”中看到,也不能从服务器状态或 apache 日志中看到,我说邪恶树是因为它基本上创建了数百个带有子级子级的进程...
简而言之:
Fork with apache会起作用吗?是的...绝对
不要滥用它
希望这会对某人有所帮助
I'll try to be quick and concise,
Using "fork" through apache it is possible, you need to "install" then enable the functions in the php.ini, finally you need to add the extension in the apache directori (a symlink would have the job done as well)
Ex:
On the other hand, I've been using forking for a lot of projects and it is really great at optimizing most of them, however, there is a bug when abusing of it with apache, im basically forking the forked child and doing anykind of hardcore stuff and it works... pretty good, but under load it works for some time before start to creating zombie process, i can manage the zombie process using "pcntl_signal(SIGCHLD, SIG_IGN);" which basically will remove the process as soon as the child finish their task, this help a little bit, then is when apache goes crazy, and start threading itself and finally crashing your server, i cannot explain this behavior (yet, but i will) this weir/evil tree created by apache can only be seen from "ps" nor from server-status or apache logs, and i said evil tree because it basically creates hundred of process with children of children...
in nutshell:
Fork with apache will work? YES... absolutely
just dont abuse of it
hope this will help some one
我刚刚尝试通过apache使用pcntl_fork,奇怪的情况是,在fork一个子进程后,父进程将标准输出(浏览器)提供给其子进程。因此,您可以想象,浏览器无法接收父进程的输出。
I have just tried to use pcntl_fork via apache, the strange situation is that after fork a child process, the parent give the standard output(browser) to its child. So, you can image, the browser cann't receive the output from the parent process.