nginx源码阅读(四).创建子进程(worker和cache)

本文详细介绍了nginx如何创建worker进程,重点解析了ngx_spawn_process函数,以及ngx_process_t结构体在子进程通信中的作用。通过socketpair实现父子进程通信,并探讨了子进程间通信的可能性,分析了文件描述符在进程间传递的过程。
摘要由CSDN通过智能技术生成
前言

在上一小节中,我们主要分析了master进程的工作循环。本小结中,我们将看到nginx是如何创建worker进程的。在上一小节中分析master进程的工作循环时,调用了ngx_start_worker_processes函数,但是其内部调用的创建子进程的代码在ngx_spawn_process中。

ngx_spawn_process

创建进程自然想到的就是调用fork函数。ngx_spawn_process函数中调用了fork来完成对子进程的创建。
先分析一下该函数参数:
1. ngx_cycle_t *cycle:给子进程的

  1. ngx_spawn_proc_pt proc:函数指针,定义为:typedef void (*ngx_spawn_proc_pt) (ngx_cycle_t *cycle, void *data);。proc函数指针指向worker进程要执行的工作循环。
  2. void *data:proc回调函数的参数
  3. char *name:进程的名字,worker进程对应的是worker process
  4. ngx_int_t respawn:创建子进程时的属性,目前可以的取值为:

    //子进程退出时,父进程不会再次创建(在创建cache loader process时使用)
    #define NGX_PROCESS_NORESPAWN -1
    //区别旧/新进程的标识位
    #define NGX_PROCESS_JUST_SPAWN -2
    //子进程异常退出时,父进程重新生成子进程的标识位
    #define NGX_PROCESS_RESPAWN -3
    //区别旧/新进程的标识位
    #define NGX_PROCESS_JUST_RESPAWN -4
    //热代码替换,父、子进程分离的标识位
    #define NGX_PROCESS_DETACHED -5

ngx_spawn_process的源码如下:

ngx_pid_t
ngx_spawn_process(ngx_cycle_t *cycle, ngx_spawn_proc_pt proc, void *data,
    char *name, ngx_int_t respawn)
{
    u_long     on;
    ngx_pid_t  pid;
    ngx_int_t  s;   //s为创建进程时,在全局数组ngx_processes的下标

    //若大于0,则代表respawn下标对应的进程需要重启
    if (respawn >= 0) {
        s = respawn;

    } else {
        //在ngx_processes数组中找到一个空位用于启动进程
        for (s = 0; s < ngx_last_process; s++) {
            if (ngx_processes[s].pid == -1) {
                break;
            }
        }
        //NGX_MAX_PROCESSES宏定义为1024,代表可创建的进程最大数
        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;
        }
    }

    //不是热代码替换
    if (respawn != NGX_PROCESS_DETACHED) {

        /* Solaris 9 still has no AF_LOCAL */
        //调用socketpair为新的worker进程创建一对socket,后面会用于进程间通信
        if (socketpair(AF_UNIX, SOCK_STREAM, 0, ngx_processes[s].channel) == -1)
        {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "socketpair() failed while spawning \"%s\"", name);
            return NGX_INVALID_PID;
        }

        ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0,
                       "channel %d:%d",
                       ngx_processes[s].channel[0],
                       ngx_processes[s].channel[
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值