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

nginx信号的实现

2016-04-15 14:23 573 查看
1.nginx信号结构体:

typedef struct {

int signo; /* 信号值 */

char signame; / 信号名 */

char name; / 信号可读名 */

void (handler)(int signo); / 信号处理程序 */

} ngx_signal_t;

当nginx收到相关的信号的时候就会执行对应得handler

2.signals数组,内部的每个元素都是ngx_signal_t,对应得handler为ngx_signal_handler,该数组是一直存在的

其中比较特殊的俩个信号:

实际上,对nginx的31号和13号信号,sigaction将SIG_IGN=0x1注册(登记)为其signal的handler。即将这两个信号交给系统(init进程)处理。

另:忽略SIGCHLD信号,常作为提高并发服务器性能的一个技巧。因为并发服务器可能fork很多子进程,子进程终结后需要服务器进程wait子进程并清理资源。如果将该信号忽略,可使内核把僵尸子进程交给init进程处理,节省大量僵尸子进程占用的系统资源

3.sigaction结构:

4.ngx_init_signals()函数

ngx_int_t

ngx_init_signals(ngx_log_t *log)

{

ngx_signal_t *sig;

struct sigaction sa;

for (sig = signals; sig->signo != 0; sig++) {   /* signals数组 */
ngx_memzero(&sa, sizeof(struct sigaction)); /* 此处sigaction是一个结构类型 */
sa.sa_handler = sig->handler;
sigemptyset(&sa.sa_mask);    /* 清空sa_mask */
if (sigaction(sig->signo, &sa, NULL) == -1) { /* 设置sig->signo信号的action,此处sigaction为系统API */
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
"sigaction(%s) failed", sig->signame);
return NGX_ERROR;
}
}

return NGX_OK;


}

5..ngx_signal_handler()函数

该函数仅根据其收到的信号对相应的全局变量,如ngx_quit, ngx_terminate, ngx_noaccept等进行赋值(均赋值为1),当该进程发现相应变量为1时,即会采取相应的操作

前面讲的都是信号的初始化,下面讲的是信号如何在进程之间进行传递

信号往往是给master进程发送的,且nginx的发送信号会有一个新的进程ngx_process=NGX_PROCESS_SIGNAMMER=2来完成,ngx_process是一个全局变量

1》通过-s选项启动nginx,只处理4种信号,stop,quit,reopen,reload

ngx_get_option()会将reopen信号赋值给全局变量ngx_signal,并将ngx_process赋值为上面那个,且该命令会启动一个新的nginx进程,并进入main函数开始执行,并直接调用ngx_signal_process,

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()发送信号

ngx_os_signal_process:

遍历signals数组,根据给定信号name,找到对应signo;

调用kill向该pid发送signo号信号

kill(pid,sig->signo(信号值))(系统调用)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: