文章3:Nginx中与信号有关的内容

来源:互联网 发布:衡水学霸有多努力知乎 编辑:程序博客网 时间:2024/05/22 06:19
欢迎转载,转载请注明出处http://blog.csdn.net/yankai0219/article/details/8453261
0.序
一概述:
二、启动时,
三、信号初始化
四、启动后的操作
五、几个小问题

0.序
     要想学好Nginx中与信号有关的内容,就必须对Linux下信号相当熟悉。因此,在学习Nginx这部分的时候最好重温一下APUE chapter 10 信号。


一概述:
     Nginx中使用信号来控制Nginx停止、平滑重启,Nginx支持以下几种信号:
     1)TERM,INT快速关闭                             SIGINT SIGTERM 即:NGX_TERMINATE_SIGNAL and SIGINT
     2)QUIT 从容关闭                                      SIGQUIT 即 NGX_SHUTDOWN_SIGNAL
     3)HUP 平滑重启,重新加载配置文件           SIGHUP 即NGX_RECONFIGURE_SIGNAL
     4)USR1 重新打开日志文件,在切割日志时用途较大 SIGUSR1 即NGX_REOPEN_SIGNAL
     5)USR2 平滑升级可执行程序                                 SIGUSR2 即NGX_CHANGEBIN_SIGNAL
     6)WINCH 从容关闭工作进程                                             即NGX_NOACCEPT_SIGNAL
二、启动时,

1.启动时,如果为./nginx -s xxxx则ngx_signal就会获得取值
  全局变量ngx_signal获得取值在ngx_get_options函数中获得 if (ngx_signal) {
        return ngx_signal_process(cycle, ngx_signal);
    }
ngx_signal_process:
首先:从存放pid的文件中读取pid 然后关闭文件
其次:进入ngx_os_signal_process
          遍历signal数组,找到匹配的信号并通过kill 杀死进程

三、信号初始化
     ngx_init_signals 函数的主要作用:通过sigaction函数设置signal数组中与指定信号相关联的处理动作。
signals数组如下所示:只是列举了一部分
ngx_signal_t  signals[] = {
    { ngx_signal_value(NGX_RECONFIGURE_SIGNAL),
      "SIG" ngx_value(NGX_RECONFIGURE_SIGNAL),
      "reload",
      ngx_signal_handler },
............................
    { 0, NULL, "", NULL }
};关于这部分内容详见1)nginx源码分析—信号初始化
                              2)参见APUE p261 10.14 sigaction函数
ngx_int_t
ngx_init_signals(ngx_log_t *log)
{
    ngx_signal_t      *sig;
    struct sigaction   sa;

    for (sig = signals; sig->signo != 0; sig++) {
        ngx_memzero(&sa, sizeof(struct sigaction));
        sa.sa_handler = sig->handler;
        sigemptyset(&sa.sa_mask);
        if (sigaction(sig->signo, &sa, NULL) == -1) { /*设定每个SIGXXX的信号处理程序*/
            ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
                          "sigaction(%s) failed", sig->signame);
            return NGX_ERROR;
        }
    }

    return NGX_OK;
}

四、启动后的操作
.启动以后,如果要停止或者平滑重启,命令为$./nginx -s stop / reload
    在master进程中的cycle函数ngx_master_process_cycle中
关于这部分内容 要参考APUE p256 10.11 信号集
1)设置信号集set 
2) 通过sigsuspend函数等待信号到来,当收到./nginx -s stop 命令时,sigsuspend就会被触发。
 sigsuspend(&set);
3)之后向子进程发出相关信号。这部分内容就是master进程与worker进程的通信。将ngx_master_process_cycle中内容提炼处理

 sigemptyset(&set);/*信号集清空,必须操作*/
/*向信号集中添加要阻塞的信号*/
 sigaddset(&set, SIGCHLD);
    sigaddset(&set, SIGALRM);
    sigaddset(&set, SIGIO);
    sigaddset(&set, SIGINT);
    sigaddset(&set, ngx_signal_value(NGX_RECONFIGURE_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_REOPEN_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_NOACCEPT_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_TERMINATE_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_CHANGEBIN_SIGNAL));
/*将信号集中的信号添加到信号屏蔽字中*/
sigprocmask(SIG_BLOCK, &set, NULL);
/*清空信号集,供sigsuspend使用*/
sigemptyset(&set);
 sigsuspend(&set);/*等到信号到来。当有信号到来时,解除信号的阻塞,进程暂停
在进程暂停过程中会执行信号处理函数,在signals数组中有设置。比如reload其处理函数为ngx_signal_handler 。当执行完信号处理函数ngx_signal_handler后,进程继续运行,继续执行sigsuspend下面的代码*/
接下来master进程将“陷入”死循环中守护着worker进程,担当起伟大的幕后工作。
在master cycle中调用了sigsuspend(),因而将master进程挂起,等待信号的产生

主要过程就是:这些都是标准的信号处理的过程。
【收到信号】,
【调用信号处理函数(在初始化过程中注册了)】,
【设置对应的全局变量】,
【sigsuspend函数返回,判断各个全局变量的值并采取相应的动作】
五、几个小问题:来自于文章 nginx源码分析—信号初始化

5.1ngx_signal_value宏是如何得到整数的信号值signo的? 

举个例子,NGX_RECONFIGURE_SIGNAL=HUP,因此ngx_signal_value(NGX_RECONFIGURE_SIGNAL)=SIGHUP

从上述signals数组可以看出,SIGHUPsigno=1name"reload"。那么,这个1是在哪里定义的?

——这很容易能想到kernel源代码。果期不然,在#include <signal.h>

#define SIGHUP          1
#define SIGINT          2
#define SIGQUIT          3
#define SIGILL          4
#define SIGTRAP          5
#define SIGABRT          6
#define SIGIOT          6
#define SIGBUS          7
#define SIGFPE          8
.........................

参考文章:
http://blog.csdn.net/livelylittlefish/article/details/7308100 

版权声明:本文为博主原创文章,未经博主允许不得转载。

0 0