您的位置:首页 > 运维架构 > Nginx

nginx源码分析—如何发送信号

2012-02-29 23:09 661 查看
作者:阿波

链接:/article/1451041.html

Content
0.序
1.发送信号
(1)通过命令行"-s"选项启动nginx
(2) ngx_signal_process()函数处理
(3) ngx_os_signal_process()函数处理
2.小结
0. 序

本文主要分析nginx如何发送信号并进行处理。文中如无特别说明,.表示nginx-1.0.4代码目录,本文为/usr/src/nginx-1.0.4。

1. 发送信号

nginx的发送信号由一个新的进程ngx_process=NGX_PROCESS_SIGNALLER=2来完成。主要有以下3步完成。

(1) 通过命令行"-s"选项启动nginx

对发送的信号,只处理4种:"stop", "quit", "reopen", "reload"。发送方式如下。请参考ngx_get_options()函数对"-s"选项的处理。

# ./nginx -s reopen

ngx_get_options()会将"reopen"信号赋值给全局变量ngx_signal,并将ngx_process赋值为NGX_PROCESS_SIGNALLER=2。且该命令会启动一个新的nginx进程,并进入main()函数开始执行, 并直接调用ngx_signal_process(),如下。

if (ngx_signal) {
        return ngx_signal_process(cycle, ngx_signal);
    }

可自行实验,即开启nginx,再另外开启nginx发送信号,查看nginx进程的变化。

(2) ngx_signal_process()函数处理
该函数作用:

读取ngx_core_module模块的配置结构ngx_core_conf_t;
根据配置结构找到其工作进程文件,如"/usr/local/nginx/logs/nginx.pid"(该文件保存nginx进程ID,即pid);
打开该文件,读取pid;
调用ngx_os_signal_process()发送信号;


(3) ngx_os_signal_process()函数处理

遍历signals数组,根据给定信号name,找到对应signo;
调用kill向该pid发送signo号信号;


代码如下,其他可参考源代码。
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;
            }

            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "kill(%P, %d) failed", pid, sig->signo);
        }
    }

    return 1;
}

kill - send signal to a process

DESCRIPTION

The kill() system call can be used to send any signal to any process group or process.

If pid is positive, then signal sig is sent to the process with the ID specified by pid.

If pid equals 0, then sig is sent to every process in the process group of the calling process.

If pid equals -1, then sig is sent to every process for which the calling process has permission to send signals, except for process 1 (init), but see below.

If pid is less than -1, then sig is sent to every process in the process group whose ID is -pid.

If sig is 0, then no signal is sent, but error checking is still performed; this can be used to check for the existence of a process ID or process group ID.

For a process to have permission to send a signal it must either be privileged (under Linux: have the CAP_KILL capability), or the real or effective user ID of the sending process must equal the real or saved set-user-ID
of the target process. In the case of SIGCONT it suffices when the sending and receiving processes belong to the same session.

2. 小结

本文主要分析nginx在运行过程中如何发送信号。

Reference

#man kill
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: