据我所知,对于连接到服务器的每个客户端,PHP都会为它生成一个新线程.但是我想知道它是否真实,如果它是真的,这个线程能活多久?该线程是否正确维护所有静态变量?(像数据库连接)
当这个线程被销毁时,它是否会调用所有析构函数?
小智 8
这完全取决于如何使用服务器设置PHP.我更熟悉Apache/PHP组合(而不是用PHP设置说Nginx和FastCGI),所以关注这个领域:
PHP通常作为DSO(动态共享对象)模块集成到Apache中.
现在,通常在Linux/Unix下的Apache通常被设置为"预分叉"模型 - 即,当它启动时,一堆子进程被分叉(确切的数字可以通过Apache指令配置),并且它们位于'进程池准备好处理请求.
当请求到达时,内核调度程序从池中选择一个Apache进程(如果可用),并由子进程处理请求.
基于Apache设置,如果它检测到需要执行PHP脚本,则按照(1)中的设置将其交给PHP DSO.
因此,在每个请求的基础上不涉及分叉或线程,这是有效的.所有请求上下文都传递给PHP层,后者开始编译并执行PHP脚本.
注意:如果启用了操作码缓存,则可以绕过编译步骤 - 即,编译PHP脚本上的第一个请求,并缓存其关联的操作码以便为后续请求重用(它是所有子进程共享的全局缓存).由于编译步骤很昂贵(解析脚本等等),对于生产系统,最好启用操作码缓存.
当PHP脚本完成时,它进入清理例程(内置于PHP DSO),它将清理每个请求的内存,关闭所有文件描述,包括db句柄(基于它的打开方式).一些PHP方法具有"持久"句柄(例如,打开数据库连接,文件句柄),这些句柄可以跨请求保存,因此您用于打开特定资源的功能很重要(其各自的文档突出显示).默认情况下,大多数资源仅在PHP请求的生命周期中保留,并且在PHP请求完成后会被销毁.
关于PHP对象dtors,这一切都取决于创建对象的范围.因此,对于全局对象,其dtors将仅在请求周期结束时被调用,而其中一些将在函数返回时超出范围时被调用.
因此,您可以免费获得内存/资源管理.您可以通过unset()调用立即触发空闲来控制它.同样从PHP 5.3开始,也可以在请求处理阶段启用垃圾收集 - 请在此处查看更多详细信息:http: //www.php.net/manual/en/features.gc.php
现在,这个Apache子程序(运行PHP脚本)重新进入准备好处理下一个请求的进程池,如步骤3所示.
我上面描述的是Linux/Unix环境中Apache/PHP的典型特征,但我认为类似的情况也适用于Microsoft设置.
同样使用nginx和FastCGI + PHP,我认为同样的循环也适用 - 即在PHP + FastCGI模块处理的请求周期结束时清理事物.这也是当nginx启动时,它将启动由FastCGI + PHP模块处理的单独进程池,并且nginx和FastCGI + PHP之间的通信发生在unix套接字中.
希望这可以帮助.
它不是PHP,而是处理请求的Web服务器.PHP本身并不运行.如果网页包含PHP代码,则此类请求将由适当的PHP SAPI模块委派给PHP.有多线程,多进程Web服务器,甚至可以想象单进程Web服务器,因此如果为请求创建单独的线程或进程,它纯粹依赖于Web服务器.
在PHP文档的许多地方,你可以遇到像这样的行umask():
避免在多线程Web服务器中使用此功能.最好在创建文件后使用chmod()更改文件权限.使用umask()可能会导致并发运行脚本和Web服务器本身的意外行为,因为它们都使用相同的umask.
......这个线程活了多久?该线程是否正确维护所有静态变量?(像数据库连接)
你听起来像一个C++背景.您可能在PHP中表示全局变量.PHP内置了对数据库连接的支持,你不必担心这些事情.它们是实现细节.大多数SAPI提供持久的数据库连接,但这只是为了您的好奇心.每个进程创建一个持久连接,用于处理请求.所以在这种情况下,它们由一个进程而不是一个进程来维护.
当这个线程被销毁时,它是否会调用所有析构函数?
在PHP中,脚本完成执行时会调用析构函数.从PHP开发人员的角度来看,脚本所处的位置无关紧要.
| 归档时间: |
|
| 查看次数: |
1362 次 |
| 最近记录: |