nginx的进程通信分为三种类别:linux 系统与nginx 通信, master 进程与worker进程通信, worker进程间通信。
master进程管理worker进程
linux 系统与nginx是通过信号才进行通信的,通过信号控制nginx重启、关闭以及加载配置文件等。
./nginx –s quit
向master进程发送信号
这里有一点是:执行 ./nginx –s quit 实际上是新开了一个master进程,只不过它半路夭折了,即向原master发送信号后,它就死掉啦。它存在的意义就是向原master发送信号。
nginx 通过 -s 知道用户要给nginx 发送信号,会有相应的动作。
ngx_get_options
case 's':
if (*p) {
ngx_signal = (char *) p;
}
if (ngx_strcmp(ngx_signal, "stop") == 0
|| ngx_strcmp(ngx_signal, "quit") == 0
|| ngx_strcmp(ngx_signal, "reopen") == 0
|| ngx_strcmp(ngx_signal, "reload") == 0)
{
ngx_process = NGX_PROCESS_SIGNALLER;
goto next;
}
要发送信号,需要知道master进程的pid,那如何获得呢?nginx 启动的时候将其写入了本地文件中。
ngx_int_t
ngx_signal_process(ngx_cycle_t *cycle, char *sig)
{
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
file.name = ccf->pid;
file.fd = ngx_open_file(file.name.data, NGX_FILE_RDONLY,
NGX_FILE_OPEN, NGX_FILE_DEFAULT_ACCESS);
n = ngx_read_file(&file, buf, NGX_INT64_LEN + 2, 0);
pid = ngx_atoi(buf, ++n);
return ngx_os_signal_process(cycle, sig, pid);
}
file.name即为配置文件中指定pid所在的文件,该文件存放master的pid。通过配置文件中的pid字段,指明存放进程id文件的地址。
ngx_int_t
ngx_os_signal_process(ngx_cycle_t *cycle, char *name, ngx_int_t pid)
{
ngx_signal_t *sig;
for (sig = signals; sig->signo != 0; sig++) {
if (ngx_strcmp(name, sig->name) == 0) {
if (kill(pid, sig->signo) != -1) {
return 0;
}
}
}
return 1;
}
根据name到ngx_signal_t的名字中去匹配,找到信号,然后通过kill向master发送消息。