Nginx (五)
1. ngx_single_process_cycle() 函数,其逻辑相对比较简单。
a) 遍历所有模块的,如果模块有init钩子函数,调用之;
b) 接下来进入一个循环,先调用ngx_process_events_and_timers(),猜测是进行nginx事件处理,后面再分析。
c) 随后,如果是终结或是退出状态,先调用各模块中的exit_process钩子函数,接着调用ngx_master_process_exit()函数退出程序;ngx_master_process_exit() 函数先删除保存pid的文件;再调用各个模块中exit_master钩子函数,将ngx_cycle->log->file->fd;设置ngx_exit_log_file的fd;根据ngx_cycle->log设置ngx_exit_log对象;将ngx_exit_log设为ngx_exit_cycle中的log;ngx_exit_cycle设为ngx_cycle;最后销毁内存池对象。
d) ngx_reconfigure标志为1,重新创建并初始化ngx_cycle对象;(实际在做重新启动的工作)ngx_reopen标志为1,重新打开cycle->open_files中的文件。
1. ngx_master_process_cycle()函数,这个函数会启动工作进程干活,并且会处理信号量,处理的过程中会杀死或者创建新的进程。
a) 阻塞所有nginx关心的信号;
b) 设置进程的title(如果你用ps –aux来查看就可以分清master与worker进程,这就是title的作用。);
c) 按照ngx_core_conf_t中worker_processes数,启动若干个work进程;
d) 启动一个缓冲管理进程;
e) 初始化几个标志:ngx_new_binary = 0; delay = 0; live = 1;
f) 后面一个循环对不同的状态进行不同处理,而那些状态多数是进程收到的不同信号。下面是各个处理的详解:
a) delay不为0,如果收到SIGALRM信号ngx_sigalrm设为1,将delay时间乘以2;最后设置一个实时类型的计时器;
b) 挂起当前进程,等到有信号,就会从挂起状态退出,继续执行;
c) 退出挂起状态后,根据操作系统时间重新更新当前时间;
d) ngx_reap为1(收到SIGCHLD信号,有worker退出(ngx_reap==1)),调用ngx_reap_children()回收子进程;
e) 如果子进程都退出了(!live)且当前进程收到ngx_signal_value(NGX_SHUTDOWN_SIGNAL)或ngx_signal_value(NGX_TERMINATE_SIGNAL)信号,本进程进行退出处理(ngx_master_process_exit());退出处理先删除pid文件,然后将调用所有模块的进程退出钩子,销毁内存池对象;
f) 如果ngx_terminate为1,delay为0,就设成50;如果delay>1000,向work进程发送SIGKILL信号,否则向work进程发送ngx_signal_value(NGX_TERMINATE_SIGNAL)信号;
g) 如果ngx_quit为1,向work进程发送ngx_signal_value(NGX_SHUTDOWN_SIGNAL)信号,然后将所有全局listening中的socket全关闭;continue;
h) 如果ngx_reconfigure为1(ngx_signal_value(NGX_RECONFIGURE_SIGNAL)信号对应),就重新读取config文件;重新创建并初始化ngx_cycle对象,启动work进程,启动缓冲管理进程,将live设为1,调用ngx_signal_worker_processes()发送ngx_signal_value(NGX_SHUTDOWN_SIGNAL)信号;
i) ngx_new_binary为1(表示是新启动的一个进程),启动work进程,启动缓冲管理进程,然后将ngx_noaccepting设为0;continue;
j) 如果ngx_restart为1(当ngx_noaccepting=1的时候会把ngx_restart设为1,重启worker),启动work进程,启动缓冲管理进程,live设为1;
k) 如果ngx_reopen为1(ngx_signal_value(NGX_REOPEN_SIGNAL)信号对应),则重新找开log文件,调用ngx_signal_worker_processes()发送ngx_signal_value(NGX_REOPEN_SIGNAL)信号;
l) 如果ngx_change_binary为1(ngx_signal_value(NGX_CHANGEBIN_SIGNAL)信号对应),调用ngx_exec_new_binary()执行新进程;
m) 如果ngx_noaccept为1(ngx_signal_value(NGX_NOACCEPT_SIGNAL)对应),设ngx_noaccepting为1,调用ngx_signal_worker_processes()发送ngx_signal_value(NGX_SHUTDOWN_SIGNAL)信号。