PHP的启动与终止

1.2 PHP的启动与终止

PHP程序的启动可以看作有两个概念上的启动,终止也有两个概念上的终止。 其中一个是PHP作为Apache(拿它举例,板砖勿扔)的一个模块的启动与终止, 这次启动php会初始化一些必要数据,比如与宿主Apache有关的,并且这些数据是常驻内存的! 终止与之相对。 还有一个概念上的启动就是当Apache分配一个页面请求过来的时候,PHP会有一次启动与终止,这也是我们最常讨论的一种。

现在我们主要来看一个PHP扩展的生命旅程是怎样走完这四个过程的。

在最初的初始化时候,就是PHP随着Apache的启动而诞生在内存里的时候, 它会把自己所有已加载扩展的MINIT方法(全称Module Initialization,是由每个模块自己定义的函数。)都执行一遍。 在这个时间里,扩展可以定义一些自己的常量、类、资源等所有会被用户端的PHP脚本用到的东西。 但你要记住,这里定义的东东都会随着Apache常驻内存,可以被所有请求使用,直到Apache卸载掉PHP模块!

内核中预置了PHP_MINIT_FUNCTION宏函数,来帮助我们实现这个功能:

?


1

2

3

4

5

6

7

8

//抛弃作者那个例子,书才看两页整那样的例子太复杂了!

//walu是我扩展的名称

int time_of_minit;//在MINIT()中初始化,在每次页面请求中输出,看看是否变化

PHP_MINIT_FUNCTION(walu)

{

    time_of_minit=time(NULL);//我们在MINIT启动中对他初始化

    return SUCCESS;//返回SUCCESS代表正常,返回FALIURE就不会加载这个扩展了。

}

当一个页面请求到来时候,PHP会迅速的开辟一个新的环境,并重新扫描自己的各个扩展, 遍历执行它们各自的RINIT方法(俗称Request Initialization), 这时候一个扩展可能会初始化在本次请求中会使用到的变量等, 还会初始化等会儿用户端(即PHP脚本)中的变量之类的,内核预置了PHP_RINIT_FUNCTION()这个宏函数来帮我们实现这个功能:

?


1

2

3

4

5

6

int time_of_rinit;//在RINIT里初始化,看看每次页面请求的时候变不。

PHP_RINIT_FUNCTION(walu)

{

    time_of_rinit=time(NULL);

    return SUCCESS;

}

好了,现在这个页面请求执行的差不多了,可能是顺利的走到了自己文件的最后, 也可能是出师未捷,半道被用户给die或者exit了, 这时候PHP便会启动回收程序,收拾这个请求留下的烂摊子。 它这次会执行所有已加载扩展的RSHUTDOWN(俗称Request Shutdown)方法, 这时候扩展可以抓紧利用内核中的变量表之类的做一些事情, 因为一旦PHP把所有扩展的RSHUTDOWN方法执行完, 便会释放掉这次请求使用过的所有东西, 包括变量表的所有变量、所有在这次请求中申请的内存等等。

内核预置了PHP_RSHUTDOWN_FUNCTION宏函数来帮助我们实现这个功能

?


1

2

3

4

5

6

7

PHP_RSHUTDOWN_FUNCTION(walu)

{

    FILE *fp=fopen("time_rshutdown.txt","a+");

    fprintf(fp,"%ld\n",time(NULL));//让我们看看是不是每次请求结束都会在这个文件里追加数据

    fclose(fp);

    return SUCCESS;

}

前面该启动的也启动了,该结束的也结束了,现在该Apache老人家歇歇的时候,当Apache通知PHP自己要Stop的时候,PHP便进入MSHUTDOWN(俗称Module Shutdown)阶段。这时候PHP便会给所有扩展下最后通牒,如果哪个扩展还有未了的心愿,就放在自己MSHUTDOWN方法里,这可是最后的机会了,一旦PHP把扩展的MSHUTDOWN执行完,便会进入自毁程序,这里一定要把自己擅自申请的内存给释放掉,否则就杯具了。

内核中预置了PHP_MSHUTDOWN_FUNCTION宏函数来帮助我们实现这个功能:

?


1

2

3

4

5

6

PHP_MSHUTDOWN_FUNCTION(walu)

{

    FILE *fp=fopen("time_mshutdown.txt","a+");

    fprintf(fp,"%ld\n",time(NULL));

    return SUCCESS;

}

这四个宏都是在walu.c里完成最终实现的,而他们的则是在/main/php.h里被定义的(其实也是调用的别的宏,本节最后我把这几个宏给展开了,供有需要的人查看)。

好了,现在我们本节内容说完了,下面我们把所有的代码合在一起,并预测一下应该出现的结果:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

//这些代码都在walu.c里面,不再.h里

int time_of_minit;//在MINIT中初始化,在每次页面请求中输出,看看是否变化

PHP_MINIT_FUNCTION(walu)

{

    time_of_minit=time(NULL);//我们在MINIT启动中对他初始化

    return SUCCESS;

}

int time_of_rinit;//在RINIT里初始化,看看每次页面请求的时候变不。

PHP_RINIT_FUNCTION(walu)

{

    time_of_rinit=time(NULL);

    return SUCCESS;

}

PHP_RSHUTDOWN_FUNCTION(walu)

{

    FILE *fp=fopen("/cnan/www/erzha/time_rshutdown.txt","a+");//请确保文件可写,否则apache会莫名崩溃

    fprintf(fp,"%d\n",time(NULL));//让我们看看是不是每次请求结束都会在这个文件里追加数据

    fclose(fp);

    return SUCCESS;

}

PHP_MSHUTDOWN_FUNCTION(walu)

{

    FILE *fp=fopen("/cnan/www/erzha/time_mshutdown.txt","a+");//请确保文件可写,否则apache会莫名崩溃

    fprintf(fp,"%d\n",time(NULL));

    return SUCCESS;

}

//我们在页面里输出time_of_minit和time_of_rinit的值

PHP_FUNCTION(walu_test)

{

    php_printf("%d<br />",time_of_minit);

    php_printf("%d<br />",time_of_rinit);

    return;

}

  • time_of_minit的值每次请求都不变。
  • time_of_rinit的值每次请求都改变。
  • 每次页面请求都会往time_rshutdown.txt中写入数据。
  • 只有在apache结束后time_mshutdown.txt才写入有数据。

多谢 闸北陆小洪 指出的有关time_of_rinit的笔误。

上面便是PHP中典型的启动-终止模型,实际情况可能因为模式不同而有所变化, 到底PHP的启动-终止会有多少中不同变化方式,请看下一节。

时间: 2024-10-08 20:50:16

PHP的启动与终止的相关文章

第5章 进程环境(2)_进程的启动和终止

2. 进程启动和终止 2.1 C程序启动过程 (1)启动例程 ①是一段程序代码,放置在/lib/libc.so.***中.编译器在编译时会将启动例程的代码编译进可执行文件中. ②可执行程序将这段嵌入的启动例代码指代为程序的起始地址. ③当内核执行C程序时(使用exec函数),在调用main前先执行启动例程代码. (2)启动例程的作用 ①搜集命令行的参数传递给main函数中的argc和argv ②搜集环境信息构建环境表并传递给main函数 ③登记进程的终止函数 2.2 进程终止   进程终止 主要

Qt学习之如何启动和终止一个线程

先来给出每个文件的相关代码然后再加以分析 Cpp代码   //*************dialog.h**************// #ifndef DIALOG_H #define DIALOG_H #include <QDialog> #define MAXSIZE 5  //最大的线程数 class QDialogButtonBox; class QProgressBar; class QPushButton; class WorkThread; class ThreadDlg : 

多线程基础二(线程的启动、终止,线程面临的三种问题)

一.线程的启动.终止方式 启动: start native(调用外部接口启动) 终止:    stop(类似kill,暴力终止)  interrupt 中断的方式 通过指令的方式 volatile boolean stop = false; public class InterruptDemo { private static int i; public static void main(String[] args) { Thread thread = new Thread(()->{ whil

PHP也是可以直接进行守护进程的启动与终止

PHP也是可以直接进行守护进程的启动与终止的,相对于shell来说会简单很多,理解更方便,当然了PHP守护进程要实现自动重启还是要依赖于shell的 cron tab日程表,每隔一段时间去执行一次脚本看脚本是否需要重启,如果需要则杀掉进程删除RunFile文件,重新启动并在RunFile文件中写入pid. PHP写守护进程时要注意几点: 1.首先就是函数clearstatcache()函数那里,查官方手册可以知道该函数是清除文件状态缓存的,当在一个脚本中多次检查同一个文件的缓存状态时如果不用该函

nginx 服务器启动、终止、重启

启动 在linux系统下输入命令: nginx地址 -c nginx配置文件 就可启动nginx eg:/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf 终止 Linux查看nginx进程号: ps -ef|grep nginx 找到master分支上的 进程号:2195 然后执行停止命令 从容停止: 快速停止:    强制停止: 重启 重启之前,如果修改了配置文件需要检查下配置文件 检查命令: 如果配置无误: 或者

启动和终止线程

返回主页面 https://blog.csdn.net/xu__cg/article/details/52831127 理解中断 中断可以理解为线程的一个标识位属性,它表示一个运行中的线程是否被其他线程进行了中断操作(通过调用该线程的interrupt()进行操作). 运行中的线程自身通过检查是否被中断进行响应, 1.线程通过isInterrupted()来进行判断是否被中断 2.线程调用静态方法Thread.interrupted()对当前线程的中断标识位进行复位. 如果该线程处于终结状态,即

windows中启动和终止nginx的两个批处理

文件:start_nginx.bat 内容: set nginx=D:\nginx-1.9.5\set php=D:\php\start /MIN %nginx%nginx.exestart /MIN %php%php-cgi.exe -b 127.0.0.1:9000 -c %php%php.ini 文件:stop_nginx.bat 内容: set nginx=D:\nginx-1.9.5\%nginx%nginx.exe -s quittaskkill /f /im nginx.exeta

Linux upstart启动方式详解

 Ubuntu从6.10开始逐步用Upstart()代替原来的SysVinit进行服务进程的管理.RHEL(CentOS)也都从版本6开始转用Upstart代替以往的init.d/rcX.d的线性启动方式. SysVinit守护进程(sysvinit软件包)是一个基于运行级别的系统,它使用运行级别(单用户.多用户以及其他更多级别)和链接(位于/etc /rc?.d目录中,分别链接到/etc/init.d中的init脚本)来启动和关闭系统服务.SysV启动是线性.顺序的.一个S20的服务必须要等待

UNIX高级环境编程(8)进程环境(Process Environment)- 进程的启动和退出、内存布局、环境变量列表

在学习进程控制相关知识之前,我们需要了解一个单进程的运行环境. 本章我们将了解一下的内容: 程序运行时,main函数是如何被调用的: 命令行参数是如何被传入到程序中的: 一个典型的内存布局是怎样的: 如何分配内存: 程序如何使用环境变量: 程序终止的各种方式: 跳转(longjmp和setjmp)函数的工作方式,以及如何和栈交互: 进程的资源限制 ? 1 main函数 main函数声明: int main (int argc, char *argv[]); 参数说明: argc:命令行参数个数