nginx的worker-master启动之master进程

一般情况下nginx都是采用worker与master的方式启动的,这里我们将分析master进程,我们知道在nginx的main函数的最后会调用ngx_master_process_cycle函数,开始启动worker-master模式,那么我们就从这个函数开始,该函数的定义在src/os/unix/Ngx_process_cycle.c当中:
    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));

//将上面的信号集中的信号全部屏蔽
    if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) {
        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                      "sigprocmask() failed");
    }

首先就是直接屏蔽掉一些信号。接下来就是一些比较重要的创建worker进程的部分了:

//获取ngx_core_module模块的配置
    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);

//开启worker进程,相当于要执行fork了,ccf->worker_processes为需要开启的worker进程的数量
    ngx_start_worker_processes(cycle, ccf->worker_processes,
                               NGX_PROCESS_RESPAWN);
    ngx_start_cache_manager_processes(cycle, 0);

ngx_start_worker_processes函数用来创建worker进程,具体worker进程的数量在ngx_core_module模块的配置的worker_processes域存储。ngx_start_cache_manager_processes用来开启与cache相关的进程。


接下来分析ngx_start_worker_processes函数:

//开启worker进程
static void
ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type)
{
    ngx_int_t      i;
    ngx_channel_t  ch;   //通过channel传递过去的数据

    ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes");

    ch.command = NGX_CMD_OPEN_CHANNEL;    //命令

//这里的n是从配置文件中读取的,表示需要有多少个worker进程,那么就fork出来多少个worker进程
    for (i = 0; i < n; i++) {

        cpu_affinity = ngx_get_cpu_affinity(i);
//在这里创建work进程,ngx_worker_process_cycle为该woker进程的执行函数,执行函数的数据位空,
        ngx_spawn_process(cycle, ngx_worker_process_cycle, NULL,
                          "worker process", type);
//初始化ch的值,ngx_process_slot是刚刚fork出来的进程在ngx_processes数组中的位置
        ch.pid = ngx_processes[ngx_process_slot].pid;
        ch.slot = ngx_process_slot;
//将socketpair的chanel0,也就是写端的描述符传递给其他的进程
        ch.fd = ngx_processes[ngx_process_slot].channel[0];
//向其他的worker传递channel
        ngx_pass_open_channel(cycle, &ch);
    }
}
这里有比较需要注意的地方是,通过一个n循环,调用n次ngx_spawn_process函数创建n个worker进程,在 ngx_spawn_process函数中会将刚刚建立的进程描述符存起来,这里又涉及到一个全局数组ngx_processes(定义在Ngx_process.c文件当中),它用来保存所有worker进程的一些信息,然后会创建一些chanel命令,用于命令以前已经建立的worker进程,让他们跟新socketpair的信息,这是用于进程间通信的,具体的以后再说吧。


这些都执行完了以后,就可以开始进入master进程的主循环了,其实master进程的主循环很是没有意思,说白了就是响应一些信号,调用sigsuspend函数等待信号,这里master进程的信号处理函数在main函数里面都已经初始化完成了,其实他们都是同一个信号处理函数ngx_signal_handler,定义在Ngx_process.c文件当中。该函数会判断接收到的信号,然后设置相应的参数,master进程的主循环就通过这些参数判断接受了哪些信号,然后进行相应的处理。


 那么到这里就写完了master进程的,擦。。其实感觉好水,有些东西还是没有弄的太懂,就这样吧。。以后再弄,接下来的文章写worker进程吧

你可能感兴趣的:(nginx的worker-master启动之master进程)