nginx的worker-master启动之worker进程

本文详细阐述了nginx的worker进程启动过程,从master进程调用start_worker_process函数开始,深入到ngx_spawn_process函数的使用,探讨了fork创建worker进程的关键步骤,以及worker进程如何进行初始化并进入主循环,处理来自master的命令和事件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

嗯,这篇文章主要讲worker进程,从哪里开始讲呢,在上面的文章我们已经知道在master进程中会调用start_worker_process函数开启worker进程,在该函数中会调用ngx_spawn_process函数真正的创建worker进程,那么就从ngx_spawn_process函数开始吧(src/os/unix/Ngx_process.c):

其实函数还是比较简单的,首先是:

//找到ngx_processes中一个空闲的位置,用来放置fork出来的进程的信息
    if (respawn >= 0) {
        s = respawn;

    } else {
        for (s = 0; s < ngx_last_process; s++) {
            if (ngx_processes[s].pid == -1) {
                break;
            }
        }
//达到最大的进程限制了
        if (s == NGX_MAX_PROCESSES) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
                          "no more than %d processes can be spawned",
                          NGX_MAX_PROCESSES);
            return NGX_INVALID_PID;
        }
    }
这部分代码主要是在全局变量ngx_processes中找到一个空闲的位置,用来保存待会创建的子进程的信息。


接下来的部分是创建socketpair,用于进程间的通信,这里就不细写了,以后写进程间通信的部分再写吧。好吧接下来就是等了好久的fork函数了:

 pid = fork();

    switch (pid) {

    case -1:
        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                      "fork() failed while spawning \"%s\"", name);
        ngx_close_channel(ngx_processes[s].channel, cycle->log);
        return NGX_INVALID_PID;

    case 0:   //子进程,开始执行它的函数
        ngx_pid = ngx_getpid();
        proc(cycle, data);     //执行work进程的进程函数
        break;

    default:
        break;
    }
子进程直接运行传进来的worker进程的运行函数即可了,该函数为ngx_worker_process_cycle,定义在Ngx_process_cycle.c当中,现在来看这个函数吧,好吧,首先是一句代码:
ngx_process = NGX_PROCESS_WORKER;   //修改该子进程全局变量ngx_process的值表示为worker进程
这里用来表示当前进程是worker进程。
worker进程的运行函数首先会调用ngx_worker_process_init函数初始化,那么还是先看这个函数吧。

其实这个函数重要的代码页没多少,首先是获取ngx_core_module模块的配置,然后通过它设置一些类似于优先级的东西。然后又一段比较重要的代码:

//在这里进行各个模块的初始化,这样保证每一个fork出来的子进程都可以访问模块
    for (i = 0; ngx_modules[i]; i++) {
        if (ngx_modules[i]->init_process) {
            if (ngx_modules[i]->init_process(cycle) == NGX_ERROR) {
                /* fatal */
                exit(2);
            }
        }
    }
因为这里已经是在worker子进程当中运行了,所以每个子进程都会从master进程中继承全局变量ngx_modules,当然还有许多的其他变量。这里会循环遍历所有的模块,调用它们的init_process函数,这样可以保证它们在当前worker进程中可以用,ngx_worker_process_init剩下的代码就是关于设置进程间通信的了,以后再说。


现在回到ngx_worker_process_cycle函数,当初始化完成了以后,那么就可以直接进入worker进程的主循环了,处理一些从master传过来的命令,具体命令式怎么传过来的以后再讲。接着解释调用很重要的函数ngx_process_events_and_timers来处理所有的事件以及定时。

好了,worker进程也差不多了,下面的文章讲进程间的通信。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值