本文档的Copyleft归L.L所有,使用GPL发布,可以自由转载,转载时请务必以超链接形式标明文章原始出处,严禁用于任何商业用途。
email: cc.dd.14@163.com
来源: http://blog.csdn.net/ccdd14
回到ngx_init_cycle函数,遍历NGX_CORE_MODULE模块,调用它们注册的init_conf钩子。只有ngx_core_module模块注册了这个钩子-----ngx_core_module_init_conf,初始化ngx_core_conf_t结构,获取用户名,用户id,组id,设置lockfile文件。
ngx_open_listening_sockets函数创建套接口,设置套接口选项,如果不使用AIO,则设置为非阻塞套接口,最后listen。
接着遍历所有模块注册的init_module钩子,只有ngx_event_core_module模块注册了------ngx_event_module_init,输出选择使用的事件模型,判断worker_connections是否超过限制,初始化几个全局变量ngx_timer_resolution,ngx_accept_mutex_ptr,ngx_random_number。
最后将结果返回给ngx_cycle,终于将ngx_init_cycle分析完成。
回到main的怀抱里。ngx_init_signals安装信号处理函数,ngx_daemon将nginx设置为后台进程。
最后看看ngx_master_process_cycle,进程的初始化工作在这里完成。
ngx_start_worker_processes功能是启动工作者线程。ngx_spawn_process创建unix域套接口,用于父子进程间的通信。进程信息存储在ngx_processes中。启动子进程函数-----ngx_worker_process_cycle,重要的工作在ngx_worker_process_init里面完成。设置进程环境,进程优先级,进程资源限制,进程cpu掩码,接着初始化所有模块的init_process钩子,其中ngx_event_core_module注册的ngx_event_process_init是非常重要的一个钩子(很多模块都没注册这个钩子)。
ngx_event_process_init根据默认情况初始化ngx_use_accept_mutex = 1,ngx_accept_mutex_held = 0,ngx_accept_mutex_delay = 500,然后创建了用于事件的定时器红黑树,接着遍历NGX_EVENT_MODULE模块的context,调用action的init钩子,epoll模型下是ngx_epoll_init函数,看看epoll模块注册的其他action。
ngx_epoll_init创建了epoll句柄,添加aio事件,设置ngx_event_flags=NGX_USE_CLEAR_EVENT | NGX_USE_GREEDY_EVENT | NGX_USE_EPOLL_EVENT。然后,ngx_event_process_init函数初始化ngx_cycle里的connections,read_events(注意rev[i].instance = 1),write_events。它们构建了连接,读写事件的数组。然后对每个listen的socket都创建一个空闲连接,注册连接的读事件handler,rev->handler = ngx_event_accept,最后将事件添加到epoll中(实际上ngx_use_accept_mutex = 1,所以没有在这个地方添加事件)。
ngx_add_channel_event将父子进程的unix域套接口的fd加入到epoll事件中,注册ev->handler = ngx_channel_handler,接收父进程的指令信息,做相应的处理,如退出。
完成子进程的初始化后(ngx_worker_process_init),进入子线程的主循环,关键函数是ngx_process_events_and_timers,事件的添加和处理都在这个函数里完成,详细分析一下这个函数。
small;">
epoll注册的事件处理函数是ngx_epoll_process_events,然后下面几个语句一直不是很明白,希望有朋友帮忙解答:
ngx_start_worker_processes调用的最后一个函数是ngx_pass_open_channel,功能是将channel的fd传送给子进程。至此,工作者线程初始化和启动完成。
ngx_start_cache_manager_processes函数启动文件cache管理进程。先判断 是否有注册pathes的manager钩子,目前有ngx_http_proxy_module模块,ngx_http_fastcgi_module模块注册了manager,loader,分别在下面的两个钩子里注册的:
看看ngx_http_file_cache_set_slot钩子里注册的函数:cache->path->manager = ngx_http_file_cache_manager,cache->path->loader = ngx_http_file_cache_loader。然后启动cache manager进程和cache loader进程。注册的子进程函数都是ngx_cache_manager_process_cycle,先初始化进程环境,接着关闭所有socket,主循环是对ngx_process_events_and_timers的调用。关键是传给子进程的两个不同参数:
ngx_cache_manager_process_handler主要功能就是调用注册的manager钩子,而ngx_cache_loader_process_handler则是调用注册的loader钩子。
最后进入父进程的主循环,主要就是信号的处理,更新nginx当前时间,这个不再细说。
哈......nginx的初始化流程分析结束。