1.2 PHP 的启动与终止PHP 程序的启动可以看做有2个概念上的启动,终止也有2个。其中一个是 PHP 作为 Apache(举例)的一个模块的启动和终止,这次启动PHP会初始化一些必要的数据,比如与宿主apache有关的,并且这些数据是常驻内存的。终止与之相对。还有一个概念上的启动就是当 apache 分配一个页面请求过来的时候,php 会有一次启动与终止。在最初的初始化的时候,就是 php 随着 apache 的启动而诞生在内存的时候,它会把自己所有已加载的扩展的 MINIT方法(全场 module initialization, 是由每个模块自己定义的函数)都执行一遍。在这个时间里,扩展可以定义一些自己的常量,类,资源等所有会被用户的 php 脚本用到的东西。但要记住,这里定义的东西会在 apache 常驻内存,可以被所有请求使用,直到 apache卸载掉 php 模块。内核中预置了 PHP_MINIT_FUNCTION 宏函数,来帮助我们实现这个功能:int time_of_minit; // 在 MINIT() 中初始化,在每次页面请求中输出,看是否有变化PHP_MINIT_FUNCTION(扩展名){time_of_minit = time(null);return SUCCESS;  // 返回 SUCCESS 代表正常,返回 FALIURE 就不会加载这个扩展了}当一个页面请求到来的时候,php 会迅速的开辟一个新的环境,并重新扫描自己的各个扩展,遍历执行它们各自的 RINIT方法(俗称 request initialization),这个时候扩展可能会初始化本次请求中会用到的变量等,还会初始化用户端(即 php 脚本)中的变量之类的,内核预置了 PHP_RINIT_FUNCTION()这个宏函数来帮我们实现这个功能:int time_of_minit;PHP_RINIT_FUNCTION(扩展名){time_of_minit=time(null);return SUCCESS;}好了,现在这个页面请求执行的差不多了,可能是顺利的走到了自己文件的最后。也可以被用户的 die 或者 exit 了,这个时候 php 就会启动回收程序。它这次会执行所有已经加载的扩展的 RSHUTDOWN(request shutdown)方法,这个时候扩展可以抓紧利用内核的变量表之类的做一些事情,因为一旦 php 把所有扩展的 RSHUTDOWN 方法执行完,便会释放这次请求使用过的所有东西,包括变量表的所有变量,所有在这次请求中申请的内存等。内核预置了 PHP_RSHUTDOWN_FUNCTION() 宏函数来帮助我们实现。PHP_RSHUTDOWN_FUNCTION(扩展名){FILE *fp=fopen('time_rshutdown.txt', 'a+');fprintf(fp, "%ld\n", time(null)); // 每次请求结束都在这里追加数据fclose(fp);return SUCCESS;}当 apache 终止时,会通知 php 自己要 stop 了。 php 便进入 MSHUTDOWN(module shutdown)阶段。这个时候 php 便会给所有的扩展下最后通牒,如果哪个扩展还有未了心事,就放在 MSHUTDOWN 方法里,一旦 php 把扩展的 MSHUTDOWN 执行完,便进入自毁程序,这里一定要把自己申请的内存给释放掉。PHP_MSHUTDOWN_FUNCTION(扩展名){FILE *fp=fopen('time_mshutdown.txt', 'a+');fprintf(fp, "%ld\n", time(NULL));return SUCCESS;}这里的4个宏是在 自己的扩展里面实现的,其他的都是在 main/php.h 里别定义的
1.4 线程安全在 PHP 初期,是作为单进程的 cgi 来运行的,所以并没有考虑线程安全的问题。我们可以随意的在全局作用域中设置变量并在程序中对它进行修改,访问,内核申请的资源如果没有被正确释放,也会在 cgi 进程结束后自动被清理干净。随着事业在多线程模式的软件越来越多,php 内核中需要一种新的资源管理方式,并最终在 php 内核中形成了一个新的抽象层:TSRM(thread safe resource management)。线程安全与非线程安全:在一个没有线程的程序中,我们往往倾向于把全局变量放在源文件的顶部,编辑器会自动的为它分配资源供我们在声明语句之下的程序逻辑中使用。但是在一个多线程的程序中,如果我们需要每个线程都拥有自己独立的资源的话,便需要为每个线程独立开辟出一个区域来存放它们各自的资源。thread-safe data pools(线程安全的资源池):在扩展的 module init 里,扩展可以调用 ts_allocate_id() 来告诉 trsm  自己需要多少资源。trsm 接收后更新系统使用的资源,并得到一个指向刚刚分配的那份资源的 id。当一个请求需要访问数据段的时候,扩展从 tsrm 层请求当前线程的资源池,以 ts_allocate_id() 返回的资源 id 来获取偏移量。因为在 php 的线程安全中构建访问全局变量资源设计到线程数据池查找对应的偏移量,这是一些额外的负载,结果就是它比对应的非线程方式(直接从编译计算好的真实全局变量地址取出数据)慢一些。非线程构建还有进程隔离的优势,这样给定的请求碰到完全出乎意料的情况时,它也不会影响到其他进程,即使是产生错误也不会导致整个 web-server 瘫痪。实际上,apache 的 MaxRequestPerChild 指令就是设计用来提升整个特性的,它经常性的有目的的 kill 掉子进程并产生新的子进程,来避免某些可能由于进程长时间运行 "积累"而来的问题(比如内存泄漏).访问全局变量:在创建一个扩展时,你并不知道它最终的运行环境是否是线程安全的。幸运的是,你要使用的标准包含文件集合中已经包含了条件定义的 ZTS 预处理标记。当 php 因为 sapi需要通过 enable-maintainer-zts 选项安装等原因以线程安全方式构建时,这个值会被自动的标记,并可以用一组 #ifdef ZTS 这样的指令集去测试它的值。就像你前面看到的,只有在 php 以线程安全方式编译时,才会存到线程安全池,只有线程安全池存在时,才会真的在线程安全池中分配空间。即使你不需要线程也需要考虑线程:正常的 php 构建默认是关闭线程安全的,只有在构建的 sapi 明确需要线程安全或线程安全在 ./configure 阶段显示打开,才会以线程安全方式构建。给出了全局查找的速度问题和进程隔离的缺点后,你看你会疑惑为什么明明不需要还有人故意打开它?这是因为,多数情况下,扩展和 sapi 的开发者认为你是线程安全开关的操作者,这样可以很大程度上保证新代码可以在所有的环境中正常运行。当线程安全启用的时候,一个名为 tsrm_ls 的特殊指针被增加到了很多的内部函数原型中。这个指针允许 php 区分不同的线程的数据。 

1.2 PHP 的启动与终止

1.PHP 扩展开始以及内核应用(1) --- PHP 的生命周期相关推荐

  1. 【php内核与扩展开发系列】PHP生命周期---启动、终止与模式

    启动与终止 PHP程序的启动可以看做有两个概念上的启动,终止也有两个概念上的终止.其中一个是PHP作为Apache(拿它举例,板砖勿扔)的一个模块的启动与终止,这次启动PHP会初始化一些必要数据,比如 ...

  2. Delphi匿名方法(三):扩展本地变量的生命周期

    本地变量,一般是随着函数执行结束,就不能再访问: 而如果在匿名函数,访问了外部函数的本地变量,本地变量的生命周期会被扩展 unit Unit1;interfaceusesWinapi.Windows, ...

  3. linux 内核维护,Linux 4.18内核系列生命周期结束:用户需尽快更新内核

    IT之家11月28日消息 著名的Linux内核维护者Greg Kroah-Hartman宣布Linux 4.18内核系列的生命周期结束,敦促用户尽快将他们的发行版升级到更新的内核. Linux 4.1 ...

  4. PHP内核的学习--PHP生命周期

    一切的开始: SAPI接口 SAPI(Server Application Programming Interface)指的是PHP具体应用的编程接口, 就像PC一样,无论安装哪些操作系统,只要满足了 ...

  5. 扩展 junit 框架_JUnit 5扩展模型的生命周期

    扩展 junit 框架 JUnit5最终版本即将来临 (当前是M4),我已经开始尝试如何编写扩展了. 在JUnit5中 ,您没有使用Runners , Rules , ClassRules等,而是只有 ...

  6. JUnit 5扩展模型的生命周期

    JUnit5最终版本即将来临 (当前是M4),我已经开始研究如何编写扩展. 在JUnit5中 ,您没有使用Runners , Rules , ClassRules等,而是只有一个Extension A ...

  7. linux内核 lts长期演进,Linux Kernel 4.19 和 5.4 生命周期延长至 6 年

    近日,Linux 内核开发及维护者 Greg Kroah-Hartman 宣布将 Linux 内核 4.19 和 5.4 版本的生命周期终止(EOL)支持从两年延长到六年,分别延长至 2024 和 2 ...

  8. spring bean生命周期_Spring中bean的生命周期和扩展点有哪些?

    前言 今天和大家分享一下Spring中Bean的生命周期的一些知识.先来说一下什么是生命周期吧,生命周期从其语义上理解就是一个对象从产生到销毁的整个过程,之所以把这个过程称为生命周期是因为其就像一个生 ...

  9. linux内核分支,新闻|Linux 内核分支 2.4 版结束生命周期

    来自 LWN 消息,Linux 内核开发者之一 Willy Tarreau 在邮件中发出信息说:Linux kernel 2.4 分支即将结束生命周期,将不会再有小版本更新. Willy Tarrea ...

  10. 秒懂SpringBoot之Spring对象生命周期与扩展点浅尝辄止

    [版权申明] 非商业目的注明出处可自由转载 出自:shusheng007 文章目录 概述 Bean的生命周期 感受Bean生命周期 具体说明 扩展点 容器级扩展点 对象级扩展点 多一点 总结 概述 I ...

最新文章

  1. 事件 ID 6008问题
  2. SAP ABAP实用技巧介绍系列之 ABAP XSLT select keyword
  3. 关于SAP UI5 CRM Reuse Fiori应用的代码审查
  4. 使用@property
  5. python 抓取电脑界面_学会了Python,我的人生跟开挂一样
  6. 嵌入式开发之davinci---IPIPE、IPIPEIF and ISIF这三者有什么区别
  7. 为什么VS提示SurfFeatureDetector不是cv的成员函数
  8. 怎样用计算机算代数,计算机与代数-如何计算sqrt-方法和实现 - 小黑电脑
  9. 鸿蒙系统pc版测评,华为MatePad Pro测评:鸿蒙系统+麒麟9000,旗舰平板封神之作?...
  10. A Complete ActiveX Web Control Tutorial
  11. Vue 集成 stylus和stylus-loader
  12. 超详细——手把手教你用threejs实现一个酷炫的模型发光扫描效果(一)
  13. hibernate中的dialect解释
  14. 目标检测之详解yolov3的anchor、置信度和类别概率
  15. TLS1之__thread
  16. 计算机系统基础实验报告
  17. 财富500强排名(2010)
  18. Java别踩白块外挂(附源码)
  19. MT6735平台UART打印问题
  20. axure 浏览器插件

热门文章

  1. All about the “paper”
  2. 使用openssl实现ECDSA签名以及验证功能(附完整测试源码)
  3. .NET-MVC站点部署到windows server2008r2服务器404错误
  4. IE6和IE7的line-height和现代浏览器不一致的问题
  5. json 后台传前台
  6. 今天遇见了setTimeout()函数
  7. ASP.NET中操作SQL数据库
  8. 是时候拥有一个你自己的命令行工具了
  9. 在react开发过程中由于setState的异步特性,获取最新state遇到问题
  10. HDU 3333-Turing Tree(BIT好题)