TCP服务器实现-start函数启动过程-factory的start过程(1)

版权声明:转载请注明来源 https://blog.csdn.net/u013702678/article/details/81229261

接着上面server的start过程,我们继续分析factory对象的start过程,这里按不同模式,factory的start过程也是不一样的,我们分别进行分析,首先分析单进程单线程模式的factory的start,其定义在E:\swoole-src-master\src\factory\Factory.c文件中,定义如下:

int swFactory_start(swFactory *factory)
{
    //标记全局变量SwooleWG的run_always属性为1,也就是一直运行。
    SwooleWG.run_always = 1;
    return SW_OK;
}

接下来我们分析多进程模式的factory的start过程,其定义在E:\swoole-src-master\src\factory\FactoryProcess.c文件中。

static int swFactoryProcess_start(swFactory *factory)
{
    int i;
    swServer *serv = factory->ptr;//获取server对象
    swWorker *worker;

    //循环创建worker,这里worker分event worker,task worker,user worker,task和user这两种是目前PHP侧可以控制的,而event worker用于外部提供event事件给reactor做管理的,后续再分析。
    for (i = 0; i < serv->worker_num; i++)
    {
        worker = swServer_get_worker(serv, i);//获取worker对象
        if (swWorker_create(worker) < 0)//创建worker的发送buffer,这里通过共享内存的方式创建,如果创建失败,则退出。
        {
            return SW_ERR;
        }
    }
    
    //设置reactor_pipe_num属性值,这个值是通过work_num和reactor_num来计算的,即表示一个reactor管理多少个worker。
    serv->reactor_pipe_num = serv->worker_num / serv->reactor_num;
    
    //在多进程模式下,除了master进程,还有manger和worker进程,这里是启动manager进程和worker进程,详情后面展开分析
    if (swManager_start(factory) < 0)
    {
        swWarn("swFactoryProcess_manager_start failed.");
        return SW_ERR;
    }
   
    //设置factory的finish回调函数
    factory->finish = swFactory_finish;
    return SW_OK;
}
static sw_inline swWorker* swServer_get_worker(swServer *serv, uint16_t worker_id)
{
    //外部提供的event worker,这里通过worker_id来区分想要的worker类型,如果worker_id小于worker_num,则worker的获取是从serv->gs->event_workers.workers[worker_id]处获取。
    if (worker_id < serv->worker_num)
    {
        return &(serv->gs->event_workers.workers[worker_id]);
    }

    //task类型的worker,如果worker_id大于worker_num,且小于task_worker_max,则获取task类型的worker,即从serv->gs->task_workers.workers[worker_id - serv->worker_num]处获取。
    uint16_t task_worker_max = serv->task_worker_num + serv->worker_num;
    if (worker_id < task_worker_max)
    {
        return &(serv->gs->task_workers.workers[worker_id - serv->worker_num]);
    }

    //用户类型的worker,如果worker_id大于task_worker_max,且小于user_worker_max,则获取用户类型的worker,即从serv->user_workers[worker_id - task_worker_max]处获取。
    uint16_t user_worker_max = task_worker_max + serv->user_worker_num;
    if (worker_id < user_worker_max)
    {
        return &(serv->user_workers[worker_id - task_worker_max]);
    }

    return NULL;
}
int swManager_start(swFactory *factory)
{
    swFactoryProcess *object = factory->object;//获取FactoryProcess对象
    int i;
    pid_t pid;
    swServer *serv = factory->ptr;//获取server对象

    //初始化FactoryProcess对象的Pipe管道信息
    object->pipes = sw_calloc(serv->worker_num, sizeof(swPipe));
    if (object->pipes == NULL)//申请空间失败
    {
        swError("malloc[worker_pipes] failed. Error: %s [%d]", strerror(errno), errno);
        return SW_ERR;
    }

    //worker进程对象的pipe初始化
    for (i = 0; i < serv->worker_num; i++)
    {   
        //创建全双工的socketpair管道,用于woker进程间通信
        if (swPipeUnsock_create(&object->pipes[i], 1, SOCK_DGRAM) < 0)
        {
            return SW_ERR;
        }
        
        serv->workers[i].pipe_master = object->pipes[i].getFd(&object->pipes[i], SW_PIPE_MASTER);//设置第i个swWorker对象的pipe_master属性,这个文件描述符记录的是管道描述符的文件ID
        serv->workers[i].pipe_worker = object->pipes[i].getFd(&object->pipes[i], SW_PIPE_WORKER);//设置第i个swWorker对象的pipe_worker属性,这个属性记录的是管道描述符文件ID
        serv->workers[i].pipe_object = &object->pipes[i];//设置worker对象的pipe_object属性
        //设置server对象connection_list的最小文件描述符ID,这个最小ID是存放在connection_list[1].fd中。
        swServer_store_pipe_fd(serv, serv->workers[i].pipe_object);
    }

    //task对象的初始化
    if (serv->task_worker_num > 0)
    {
        if (swServer_create_task_worker(serv) < 0)
        {
            return SW_ERR;
        }

        swProcessPool *pool = &serv->gs->task_workers;
        swTaskWorker_init(pool);

        swWorker *worker;
        for (i = 0; i < serv->task_worker_num; i++)
        {
            worker = &pool->workers[i];
            if (swWorker_create(worker) < 0)
            {
                return SW_ERR;
            }
            if (serv->task_ipc_mode == SW_TASK_IPC_UNIXSOCK)
            {
                swServer_store_pipe_fd(SwooleG.serv, worker->pipe_object);
            }
        }
    }

    //用户worker对象的初始化,用户worker是有绑定PHP侧的回调函数的worker的抽象
    if (serv->user_worker_num > 0)
    {
        serv->user_workers = SwooleG.memory_pool->alloc(SwooleG.memory_pool, serv->user_worker_num * sizeof(swWorker));
        if (serv->user_workers == NULL)
        {
            swoole_error_log(SW_LOG_ERROR, SW_ERROR_SYSTEM_CALL_FAIL, "gmalloc[server->user_workers] failed.");
            return SW_ERR;
        }
        swUserWorker_node *user_worker;
        i = 0;
        LL_FOREACH(serv->user_worker_list, user_worker)
        {
            memcpy(&serv->user_workers[i], user_worker->worker, sizeof(swWorker));
            if (swWorker_create(&serv->user_workers[i]) < 0)
            {
                return SW_ERR;
            }
            i++;
        }
    }

    //设置serv的message_box属性,这里通过共享内存创建
    serv->message_box = swChannel_new(65536, sizeof(swWorkerStopMessage), SW_CHAN_LOCK | SW_CHAN_SHM);
    if (serv->message_box == NULL)//创建失败
    {
        return SW_ERR;
    }

    pid = fork();//执行fork操作,则当前进程,也就是master为父进程,而fork后的进程为子进程
    switch (pid)
    {
    //子进程,也就是manager进程的逻辑
    case 0:
        SW_START_SLEEP;//等待父进程处理完
        if (serv->gs->start == 0)//这里判断swServer是否已经启动,如果未启动属于异常情况,这里只是退出。
        {
            return SW_OK;
        }
        
        //fork后,父进程创建的listen描述符在子进程也存在,这里关闭子进程的listen描述符
        swServer_close_listen_port(serv);

        //如果有task_worker_num属性,则创建task worker
        if (serv->task_worker_num > 0)
        {
            //启动task worker
            swProcessPool_start(&serv->gs->task_workers);
        }

        //创建worker进程
        for (i = 0; i < serv->worker_num; i++)
        {
            //执行实际的worker进程创建流程
            pid = swManager_spawn_worker(factory, i);
            if (pid < 0)//创建失败
            {
                swError("fork() failed.");
                return SW_ERR;
            }
            else//创建成功
            {
                serv->workers[i].pid = pid;//第i个worker保存自己的PID值
            }
        }

        //创建用户侧的worker对象
        if (serv->user_worker_list)
        {
            swUserWorker_node *user_worker;
            LL_FOREACH(serv->user_worker_list, user_worker)//遍历所有的user_worker对象
            {
                if (user_worker->worker->pipe_object)
                {
                    swServer_store_pipe_fd(serv, user_worker->worker->pipe_object);
                }
                //创建新进程,调用PHP侧的onUserWorkerStart回调函数,这里循环调用的原因是有多个worker进程,每个进程都需要回调onUserWorkerStart函数。
                swManager_spawn_user_worker(serv, user_worker->worker);
            }
        }

        SwooleG.process_type = SW_PROCESS_MANAGER;//设置属性
        SwooleG.pid = getpid();//设置全局对象SwoolG的pid属性
        exit(swManager_loop(factory));
        break;
    default://master进程的执行逻辑
        serv->gs->manager_pid = pid;//master进程负责设置全局变量manager_pid属性,也就是manager进程的进程编号
        break;
    case -1://fork失败
        swError("fork() failed.");
        return SW_ERR;
    }
    return SW_OK;
}

猜你喜欢

转载自blog.csdn.net/u013702678/article/details/81229261