Skip to content

Commit

Permalink
ngx_master_process_cycle
Browse files Browse the repository at this point in the history
  • Loading branch information
chronolaw committed Apr 6, 2016
1 parent 6f6ba0a commit e04f117
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 6 deletions.
14 changes: 14 additions & 0 deletions nginx/src/os/unix/ngx_process.c
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ ngx_spawn_process(ngx_cycle_t *cycle, ngx_spawn_proc_pt proc, void *data,
}


// 执行外部程序
ngx_pid_t
ngx_execute(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx)
{
Expand Down Expand Up @@ -391,11 +392,13 @@ ngx_signal_handler(int signo)
case NGX_PROCESS_SINGLE:
switch (signo) {

// 优雅关闭, -s quit
case ngx_signal_value(NGX_SHUTDOWN_SIGNAL):
ngx_quit = 1;
action = ", shutting down";
break;

// 直接关闭, -s stop
case ngx_signal_value(NGX_TERMINATE_SIGNAL):
case SIGINT:
ngx_terminate = 1;
Expand All @@ -409,11 +412,13 @@ ngx_signal_handler(int signo)
}
break;

// 重新加载配置文件, -s reload
case ngx_signal_value(NGX_RECONFIGURE_SIGNAL):
ngx_reconfigure = 1;
action = ", reconfiguring";
break;

// 重新打开文件, -s reopen
case ngx_signal_value(NGX_REOPEN_SIGNAL):
ngx_reopen = 1;
action = ", reopening logs";
Expand All @@ -438,6 +443,7 @@ ngx_signal_handler(int signo)
action = ", changing binary";
break;

// SIGALRM,更新时间
case SIGALRM:
ngx_sigalrm = 1;
break;
Expand All @@ -446,7 +452,10 @@ ngx_signal_handler(int signo)
ngx_sigio = 1;
break;

// 子进程结束,可能发生了意外
case SIGCHLD:
// 将导致master进程ngx_master_process_cycle()调用ngx_reap_children()
// 重新产生子进程
ngx_reap = 1;
break;
}
Expand All @@ -463,22 +472,27 @@ ngx_signal_handler(int signo)
break;
}
ngx_debug_quit = 1;

// 优雅关闭, -s quit
case ngx_signal_value(NGX_SHUTDOWN_SIGNAL):
ngx_quit = 1;
action = ", shutting down";
break;

// 直接关闭, -s stop
case ngx_signal_value(NGX_TERMINATE_SIGNAL):
case SIGINT:
ngx_terminate = 1;
action = ", exiting";
break;

// 重新打开文件, -s reopen
case ngx_signal_value(NGX_REOPEN_SIGNAL):
ngx_reopen = 1;
action = ", reopening logs";
break;

// 重新加载配置文件, -s reload
case ngx_signal_value(NGX_RECONFIGURE_SIGNAL):
case ngx_signal_value(NGX_CHANGEBIN_SIGNAL):
case SIGIO:
Expand Down
10 changes: 5 additions & 5 deletions nginx/src/os/unix/ngx_process.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ typedef struct {
char *name;

// 进程当前的状态,用于关闭时用
unsigned respawn:1;
unsigned just_spawn:1;
unsigned detached:1;
unsigned exiting:1;
unsigned exited:1;
unsigned respawn:1; //重新生成的新进程
unsigned just_spawn:1; //进程刚刚产生
unsigned detached:1; //进程已经与父进程分离
unsigned exiting:1; //进程正在退出
unsigned exited:1; //进程已经退出
} ngx_process_t;


Expand Down
16 changes: 15 additions & 1 deletion nginx/src/os/unix/ngx_process_cycle.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ static void ngx_pass_open_channel(ngx_cycle_t *cycle, ngx_channel_t *ch);
// master进程调用,遍历ngx_processes数组,用kill发送信号
static void ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo);

// 重新产生子进程
static ngx_uint_t ngx_reap_children(ngx_cycle_t *cycle);

// 删除pid,模块清理,关闭监听端口
Expand Down Expand Up @@ -120,7 +121,7 @@ ngx_master_process_cycle(ngx_cycle_t *cycle)
ngx_listening_t *ls;
ngx_core_conf_t *ccf;

// 屏蔽一些信号,master进程不关注
// 添加master进程关注的信号
sigemptyset(&set);
sigaddset(&set, SIGCHLD);
sigaddset(&set, SIGALRM);
Expand Down Expand Up @@ -188,6 +189,7 @@ ngx_master_process_cycle(ngx_cycle_t *cycle)
// 主要调用ngx_signal_worker_processes()发送信号
// ngx_start_worker_processes()产生新子进程
for ( ;; ) {
// 延时等待子进程关闭,每次进入加倍等待
if (delay) {
if (ngx_sigalrm) {
sigio = 0;
Expand Down Expand Up @@ -222,10 +224,13 @@ ngx_master_process_cycle(ngx_cycle_t *cycle)
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"wake up, sigio %i", sigio);

// 子进程可能发生了意外结束
// 在os/unix/ngx_process.c ngx_signal_handler()里设置
if (ngx_reap) {
ngx_reap = 0;
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "reap children");

// 重新产生子进程
live = ngx_reap_children(cycle);
}

Expand Down Expand Up @@ -274,6 +279,7 @@ ngx_master_process_cycle(ngx_cycle_t *cycle)
ngx_signal_worker_processes(cycle,
ngx_signal_value(NGX_SHUTDOWN_SIGNAL));

// 关闭所有监听端口
ls = cycle->listening.elts;
for (n = 0; n < cycle->listening.nelts; n++) {
if (ngx_close_socket(ls[n].fd) == -1) {
Expand Down Expand Up @@ -674,6 +680,7 @@ ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo)
}


// 重新产生子进程
static ngx_uint_t
ngx_reap_children(ngx_cycle_t *cycle)
{
Expand All @@ -688,6 +695,8 @@ ngx_reap_children(ngx_cycle_t *cycle)
ch.fd = -1;

live = 0;

// 遍历进程数组,检查所有有效的进程
for (i = 0; i < ngx_last_process; i++) {

ngx_log_debug7(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
Expand All @@ -700,10 +709,13 @@ ngx_reap_children(ngx_cycle_t *cycle)
ngx_processes[i].respawn,
ngx_processes[i].just_spawn);

// -1表示进程无效,忽略
if (ngx_processes[i].pid == -1) {
continue;
}

// 找到被意外结束的进程
// ngx_process_get_status()里设置, os/unix/ngx_process.c
if (ngx_processes[i].exited) {

if (!ngx_processes[i].detached) {
Expand Down Expand Up @@ -739,6 +751,8 @@ ngx_reap_children(ngx_cycle_t *cycle)
&& !ngx_terminate
&& !ngx_quit)
{
// 使用进程数组里保存的信息重新产生新的进程
// 仍然在原来的位置
if (ngx_spawn_process(cycle, ngx_processes[i].proc,
ngx_processes[i].data,
ngx_processes[i].name, i)
Expand Down

0 comments on commit e04f117

Please sign in to comment.