PHP:pcntl_fork() 到底做了什么?

发布于 2024-08-17 18:15:40 字数 432 浏览 6 评论 0原文

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

佼人 2024-08-24 18:15:40

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

pcntl_fork() 函数创建一个
子进程不同于
父进程仅在其 PID 和
PPID。
请查看您的系统
具体的 fork(2) 手册页
有关 fork 如何在您的设备上工作的详细信息
系统。

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

PHP 中的流程控制支持
实现 Unix 风格的进程
创建、程序执行、信号
处理和进程终止。

过程控制不应
在网络服务器内启用
环境和意想不到的结果可能
如果有任何过程控制就会发生
函数在 Web 服务器内使用
环境。

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

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

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

pcntl_fork probably works as you think it would : it forks the current process, the same way the C function fork does :

The pcntl_fork() function creates a
child process that differs from the
parent process only in its PID and
PPID.
Please see your system's
fork(2) man page for specific
details as to how fork works on your
system.

But, quoting the Introduction of the Process Control section of the manual :

Process Control support in PHP
implements the Unix style of process
creation, program execution, signal
handling and process termination.

Process Control should not be
enabled within a web server
environment and unexpected results may
happen if any Process Control
functions are used within a web server
environment.

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 :

Note: This extension is not available
on Windows platforms.

悸初 2024-08-24 18:15:40

首先,在为工作 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

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

Note: To build a multithreaded version of Apache, the target system must support threads. In this case, PHP should also be built with experimental Zend Thread Safety (ZTS). Under this configuration, not all extensions will be available. The recommended setup is to build Apache with the default prefork MPM-Module.

I also found this page with some further instructions:
http://www.stevekallestad.com/blog/apache_worker_mpm_with_php.html

明媚殇 2024-08-24 18:15:40

我会尽量快速简洁,

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

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 创建的堰/邪恶树只能从“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:

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 

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

挖个坑埋了你 2024-08-24 18:15:40

我刚刚尝试通过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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文