zoukankan      html  css  js  c++  java
  • PHP扩展-生命周期和内存管理

    1. PHP源码结构

    PHP的内核子系统有两个,ZE(Zend Engine)和PHP Core.
    ZE负责将PHP脚本解析成机器码(也成为token符)后,在进程空间执行这些机器码;ZE还负责内存管理,变量作用域管理和对PHP函数的调度管理。

    PHP Core负责和SAPI层的通信;PHP Core也为safe_mode, open_basedir的检查提供了统一控制层;PHP Core还提供了streams层,用于用户域的文件和网络IO操作。其中SAPI(Server Application Programming Interface)通常包含Nginx,Apache,IIS,CLI,CGI等主机环境。

    PHP扩展在ZE和PHP Core的基础上提供对各种常用操作的封装,比如对mysql,redis,memcache,sqlite等的读写,对json,xml文件的解析,对soap,sokcet,curl的网络协议的封装,对加密解密压缩解压缩等的封装,对图像处理的封装等等。有些扩展是从零开始实现某个功能,比如按照redis的通信协议使用C来实现和redis的通信;有些扩展则是通过调用系统已有的库,比如图片处理的gb扩展需要系统本身要安装了相应的gd库。
    在PHP源码php-5.6.24/ext中提供了78个扩展。

    总之,由ZE和PHP Core提供基础的架构,由EXT(扩展)提供用户域的各种操作。
    以php-5.6.24源码为例,ZE对应文件夹php-5.6.24/Zend, PHP Core对应文件夹php-5.6.24/main, 扩展对应文件夹php-5.6.24/ext。

    2. PHP扩展的生命周期

    PHP在接收到SAPI命令时,首先初始化并启动它的内核子系统,在内核子系统的启动快结束时,PHP开始加载它的扩展代码并对扩展初始化,此时PHP将调用每个模块的初始化例程Module Initialization routine (MINIT)。

    MINIT(Module Initialization)
    PHP调用MINIT相关例程,使得每个扩展有机会初始化内部变量、分配资源、注册资源处理句柄,以及向ZE注册自己的函数,以便于脚本调用这其中的函数时候ZE知道执行哪些代码

    RINIT(Request Initialization)
    在模块初始化完成后,PHP等待来自SAPI的请求,当接收到SAPI请求后,由ZE为当前被请求的php脚本创建运行环境,并调用每个扩展的Request Initialization(RINIT)函数,使得每个扩展有机会设定特定的环境变量,根据请求分配资源,或者执行其他任务,如审核。

    这里所说的SAPI请求分为两类,一类是Apache, IIS, 和其他成熟的web server SAPIs,他们在启动时PHP先执行了MINIT,之后等待来自用户的页面请求,当收到请求后执行RINIT;另一类SAPI请求则是CGI or CLI SAPIs,PHP在收到这类SAPI请求时,执行完MINIT马上就执行RINIT。

    当RINIT请求初始化完毕后,ZE接回控制权并将当前被请求的脚本翻译成tokens, 最终构成opcodes(操作码),opcodes被执行过程中,如果某个opcode要求执行某个扩展函数,这是ZE就会将相关参数绑定到改函数,并将控制权临时交给该函数去执行,直到该函数执行完毕。

    RSHUTDOWN(Request Shutdown)
    PHP脚本运行结束后,PHP调用每个扩展的请求关闭(RSHUTDOWN)函数以执行最后的清理工作(如将session变量存入磁盘)。接下来,ZE执行清理过程(垃圾收集),有效地对之前的请求期间用到的每个变量执行unset()。

    MSHUTDOWN(Module Shutdown)
    当RSHUTDOWN完成后,PHP继续等待SAPI的其他文档请求或者是关闭信号。对于CGI和CLI等SAPI,没有“下一个请求”,所以SAPI立刻开始关闭。关闭期间,PHP再次遍历每个扩展,调用其模块关闭(MSHUTDOWN)函数,并最终关闭自己的内核子系统。

    GINIT
    初始化全局变量

    GSHUTDOWN
    释放全局变量

    MINFO
    设置phpinfo模块的信息,phpinfo要等级每个扩展的配置信息

    // main/php.h
     #define PHP_MINIT       ZEND_MODULE_STARTUP_N
     #define PHP_MSHUTDOWN   ZEND_MODULE_SHUTDOWN_N
     #define PHP_RINIT       ZEND_MODULE_ACTIVATE_N
     #define PHP_RSHUTDOWN   ZEND_MODULE_DEACTIVATE_N
     #define PHP_MINFO       ZEND_MODULE_INFO_N
     #define PHP_GINIT       ZEND_GINIT
     #define PHP_GSHUTDOWN   ZEND_GSHUTDOWN
    
     #define PHP_MINIT_FUNCTION      ZEND_MODULE_STARTUP_D
     #define PHP_MSHUTDOWN_FUNCTION  ZEND_MODULE_SHUTDOWN_D
     #define PHP_RINIT_FUNCTION      ZEND_MODULE_ACTIVATE_D
     #define PHP_RSHUTDOWN_FUNCTION  ZEND_MODULE_DEACTIVATE_D
     #define PHP_MINFO_FUNCTION      ZEND_MODULE_INFO_D
     #define PHP_GINIT_FUNCTION      ZEND_GINIT_FUNCTION
     #define PHP_GSHUTDOWN_FUNCTION  ZEND_GSHUTDOWN_FUNCTION

    3. PHP扩展的内存管理

    ZE在执行自己内部的内存管理时,通过附加的标志来标识某某内存变量是否是持久性的,对于非持久内存,ZE会去清理。但在扩展内部最好还是自己去清理非持久内存,因为扩展自己请求分配的非持久内存,将在长时间内保持为未回收状态,这样与之相关的资源长时间得不到释放。

    参考文章:Extension Writing Part I: Introduction to PHP and Zend

    qrcode_for_gh_61c6224cfae9_258

  • 相关阅读:
    Visual Studio DSL 入门 11为状态机设计器添加规则
    不平静的2009,期待更不平静的2010
    ASP.NET MVC 2 正式发布
    [翻译] DSL和模型驱动开发的最佳实践(2/4)
    Visual Studio DSL 入门 9创建状态机的图形符号
    Visual Studio DSL 入门 6DSL的图形表示1
    智诚B2C1.31正式发
    一个程序员的创业尝试
    Visual Studio DSL 入门 13结合T4生成代码
    Visual Studio DSL 入门 10完善状态机案例
  • 原文地址:https://www.cnblogs.com/beatzeus/p/6071902.html
Copyright © 2011-2022 走看看