您的位置:首页 > 编程语言 > PHP开发

[李景山php] 深入理解PHP内核[读书笔记]--第二章:用户代码执行--SAPI概述-PHP中的CGI实现

2017-05-08 21:59 871 查看
PHP中的CGI实现

PHP的CGI实现了Fastcgi协议,是一个TCP或UDP协议的服务器接受来自Web服务器的请求,当启动时创建TCP/UDP协议的服务器的socket监听,并接收相关请求进行处理。随后就进入了PHP的生命周期:模块初始化,sapi初始化,处理PHP请求,模块关闭,sapi关闭等就构成了整个CGI的生命周期。

以TCP为例,在TCP的服务端,一般会执行这样几个操作步骤:

1 调用socket函数创建一个TCP用的流式套接字

2 调用bind函数将服务器的本地地址与前面创建的套接字绑定

3 调用listen函数将创建的套接字作为监听,等待客户端发起的连接,当客户端有多个连接连接到这个套接字时,可能需要排队处理。

4 服务器进程调用accept函数进入阻塞状态,直到有客户进程调用connect函数而建立一个连接

5 当与客户端创建连接后,服务器调用read_stream函数读取客户的请求

6 处理完数据后,服务器调用write函数向客户端发送应答

如下图:



PHP的CGI实现从cgi_main.c文件的main函数开始,在main函数中调用了定义在fastcgi.c文件中的初始化,监听等函数。对比TCP流程,我们查看PHP对TCP协议的实现,虽然PHP本身也实现了这些流程,但是在main函数中一些过程被封装成一个函数实现。对应TCP的操作流程,PHP首先会执行创建socket,绑定套接字,创建监听:

if(bindpath){
fcgi_fd = fcgi_listen(bindpath,128);//实现socket监听,调用fcgi_init初始化
}


在fastcgi.c文件中,fcgi_listen函数主要用于创建、绑定socket并开始监听,它走完了前面听列TCP流程的前三个阶段,

if((listen_socket = socket(sa.sa.sa_family,SOCK_STREAM))<0 || bind(listen_socket,(struct sockaddr *) &sa,sock_len) <0 || listen(listen_socket,backlog)<0){
}


当服务端初始化完成后,进程调用accept函数进入阻塞状态,在main函数中我们看到如下代码:

while(parent){
do{
pid = fork();//生成新的子进程
switch(pid){
parent = 0;
// don't catch our signals
sigaction(SIGTERM,&old_term,0);//终止信号,
}
}while(parent && (runing < children));
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐