日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > php >内容正文

php

php-fpm初始化失败,FPM的初始化 - [ PHP7的内核剖析 ] - 在线原生手册 - php中文网

發(fā)布時(shí)間:2025/3/8 php 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 php-fpm初始化失败,FPM的初始化 - [ PHP7的内核剖析 ] - 在线原生手册 - php中文网 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

FPM的初始化

接下來(lái)看下fpm的啟動(dòng)流程,從main()函數(shù)開(kāi)始://sapi/fpm/fpm/fpm_main.cint?main(int?argc,?char?*argv[]){

...????//注冊(cè)SAPI:將全局變量sapi_module設(shè)置為cgi_sapi_module

sapi_startup(&cgi_sapi_module);

...????//執(zhí)行php_module_starup()

if?(cgi_sapi_module.startup(&cgi_sapi_module)?==?FAILURE)?{????????return?FPM_EXIT_SOFTWARE;

}

...????//初始化

if(0?>?fpm_init(...)){

...

}

...

fpm_is_running?=?1;

fcgi_fd?=?fpm_run(&max_requests);//后面都是worker進(jìn)程的操作,master進(jìn)程不會(huì)走到下面

parent?=?0;

...

}

fpm_init()主要有以下幾個(gè)關(guān)鍵操作:

(1)fpm_conf_init_main():

解析php-fpm.conf配置文件,分配worker pool內(nèi)存結(jié)構(gòu)并保存到全局變量中:fpm_worker_all_pools,各worker pool配置解析到fpm_worker_pool_s->config中。

(2)fpm_scoreboard_init_main():?分配用于記錄worker進(jìn)程運(yùn)行信息的共享內(nèi)存,按照worker pool的最大worker進(jìn)程數(shù)分配,每個(gè)worker pool分配一個(gè)fpm_scoreboard_s結(jié)構(gòu),pool下對(duì)應(yīng)的每個(gè)worker進(jìn)程分配一個(gè)fpm_scoreboard_proc_s結(jié)構(gòu),各結(jié)構(gòu)的對(duì)應(yīng)關(guān)系如下圖。

(3)fpm_signals_init_main():static?int?sp[2];int?fpm_signals_init_main(){????struct?sigaction?act;

//創(chuàng)建一個(gè)全雙工管道

if?(0?>?socketpair(AF_UNIX,?SOCK_STREAM,?0,?sp))?{????????return?-1;

}????//注冊(cè)信號(hào)處理handler

act.sa_handler?=?sig_handler;

sigfillset(&act.sa_mask);????if?(0?>?sigaction(SIGTERM,??&act,?0)?||????????0?>?sigaction(SIGINT,???&act,?0)?||????????0?>?sigaction(SIGUSR1,??&act,?0)?||????????0?>?sigaction(SIGUSR2,??&act,?0)?||????????0?>?sigaction(SIGCHLD,??&act,?0)?||????????0?>?sigaction(SIGQUIT,??&act,?0))?{????????return?-1;

}????return?0;

}

這里會(huì)通過(guò)socketpair()創(chuàng)建一個(gè)管道,這個(gè)管道并不是用于master與worker進(jìn)程通信的,它只在master進(jìn)程中使用,具體用途在稍后介紹event事件處理時(shí)再作說(shuō)明。另外設(shè)置master的信號(hào)處理handler,當(dāng)master收到SIGTERM、SIGINT、SIGUSR1、SIGUSR2、SIGCHLD、SIGQUIT這些信號(hào)時(shí)將調(diào)用sig_handler()處理:static?void?sig_handler(int?signo){????static?const?char?sig_chars[NSIG?+?1]?=?{

[SIGTERM]?=?'T',

[SIGINT]??=?'I',

[SIGUSR1]?=?'1',

[SIGUSR2]?=?'2',

[SIGQUIT]?=?'Q',

[SIGCHLD]?=?'C'

};????char?s;

...

s?=?sig_chars[signo];????//將信號(hào)通知寫(xiě)入管道sp[1]端

write(sp[1],?&s,?sizeof(s));

...

}

(4)fpm_sockets_init_main()

創(chuàng)建每個(gè)worker pool的socket套接字。

(5)fpm_event_init_main():

啟動(dòng)master的事件管理,fpm實(shí)現(xiàn)了一個(gè)事件管理器用于管理IO、定時(shí)事件,其中IO事件通過(guò)kqueue、epoll、poll、select等管理,定時(shí)事件就是定時(shí)器,一定時(shí)間后觸發(fā)某個(gè)事件。

在fpm_init()初始化完成后接下來(lái)就是最關(guān)鍵的fpm_run()操作了,此環(huán)節(jié)將fork子進(jìn)程,啟動(dòng)進(jìn)程管理器,另外master進(jìn)程將不會(huì)再返回,只有各worker進(jìn)程會(huì)返回,也就是說(shuō)fpm_run()之后的操作均是worker進(jìn)程的。int?fpm_run(int?*max_requests){????struct?fpm_worker_pool_s?*wp;

for?(wp?=?fpm_worker_all_pools;?wp;?wp?=?wp->next)?{????????//調(diào)用fpm_children_make()?fork子進(jìn)程

is_parent?=?fpm_children_create_initial(wp);

if?(!is_parent)?{????????????goto?run_child;

}

}????//master進(jìn)程將進(jìn)入event循環(huán),不再往下走

fpm_event_loop(0);

run_child:?//只有worker進(jìn)程會(huì)到這里

*max_requests?=?fpm_globals.max_requests;????return?fpm_globals.listening_socket;?//返回監(jiān)聽(tīng)的套接字}

在fork后worker進(jìn)程返回了監(jiān)聽(tīng)的套接字繼續(xù)main()后面的處理,而master將永遠(yuǎn)阻塞在fpm_event_loop(),接下來(lái)分別介紹master、worker進(jìn)程的后續(xù)操作。

總結(jié)

以上是生活随笔為你收集整理的php-fpm初始化失败,FPM的初始化 - [ PHP7的内核剖析 ] - 在线原生手册 - php中文网的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。