nginx源代码分析 - 启动(四) 创建后台进程和worker进程

全局变量
ngx_cycle = cycle;
ngx_process = NGX_PROCESS_MASTER; 1

ngx_init_signals(cycle->log)安装信号处理函数
遍历全局signals数组
struct sigaction   sa;
ngx_memzero(&sa, sizeof(struct sigaction));
sa.sa_handler = sig->handler;
sigemptyset(&sa.sa_mask);
if (sigaction(sig->signo, &sa, NULL) == -1) {

ngx_daemon(cycle->log)后台运行
这里父进程退出了,要想继续调试,需要在gdb中加入
set follow-fork-mode child
set detach-on-fork off
catch fork

ngx_create_pidfile
/home/liuwb/Desktop/code/nginx-code/logs/nginx.pid

ngx_log_redirect_stderr
让stderr也指向/home/liuwb/Desktop/code/nginx-code/logs/error.log

ngx_master_process_cycle(cycle);

阻塞这些信号,放到信号队列中,延迟递交,如果在此期间发生了多个SIGINT信号,sigsuspend只会调用一次处理函数
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) {

sigemptyset(&set);
sigsuspend(&set);只有当有信号发生时,才会解除阻塞,调用一次信号处理函数,返回
sigsuspend实际是将sigprocmask和pause结合起来原子操作

主进程的名字
master process /home/liuwb/Desktop/code/nginx-code/objs/nginx -p /home/liuwb/Desktop/code/nginx-code/ -c conf/nginx.conf

ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
ngx_start_worker_processes(cycle, ccf->worker_processes, NGX_PROCESS_RESPAWN);
ccf->worker_processes = 2,cpu个数

创建worker线程
ngx_spawn_process(cycle, ngx_worker_process_cycle,
                  (void *) (intptr_t) i, "worker process", type);
    ngx_process_t ngx_processes[NGX_MAX_PROCESSES];最多1024个进程
    socketpair(AF_UNIX, SOCK_STREAM, 0, ngx_processes[s].channel)
    设置非阻塞
    ioctl(ngx_processes[s].channel[0], FIOASYNC, &on) IO就绪内核发送SIGIO signal
    fcntl(ngx_processes[s].channel[0], F_SETOWN, ngx_pid)设置将要在文件描述词fd上接收SIGIO 或 SIGURG事件信号的进程或进程组标识
    fcntl(ngx_processes[s].channel[0], F_SETFD, FD_CLOEXEC)
    fcntl(ngx_processes[s].channel[1], F_SETFD, FD_CLOEXEC)
    
    创建管道和子进程通信
    
    调用fork,跟踪worker进程
    ngx_worker_process_cycle
        ngx_worker_process_init(cycle, worker);
        ngx_setproctitle("worker process")
            for ( ;; )
                ngx_process_events_and_timers(cycle);
                    ngx_event_actions = ngx_epoll_module_ctx.actions;
                    (void) ngx_process_events(cycle, timer, flags);
                    ngx_epoll_process_events
        
    
ch.pid = ngx_processes[ngx_process_slot].pid;
ch.slot = ngx_process_slot;
ch.fd = ngx_processes[ngx_process_slot].channel[0];

ngx_pass_open_channel(cycle, &ch);

主进程负责配置,重启等工作

具体调试请查看下篇博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值