- //////////// nginx/src/os/unix/ngx_process_cycle.c /////////////
- //worker进程处理连接、请求的主函数
- static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
- {
- .....
- //初始化worker进程
- ngx_worker_process_init(cycle, worker);
- ngx_setproctitle("worker process");
- for ( ;; ) {
- .....
- //处理新连接以及已有连接上的新数据
- ngx_process_events_and_timers(cycle);
- .....
- }
- }
- //////////// nginx/src/event/ngx_event.c /////////////
- //检查是否有新连接,并处理事件队列中的事件
- void ngx_process_events_and_timers(ngx_cycle_t *cycle)
- {
- .....
- //检查accept锁是否启用
- if (ngx_use_accept_mutex) {
- //如果accept_disable大于0,说明当前进程负载偏高或者接受新连接异常
- //该值-1是为了尽快让该进程参与accept锁的竞争,防止一直空闲
- if (ngx_accept_disabled > 0) {
- ngx_accept_disabled--;
- } else {
- //尝试获取accept,如果获取成功ngx_accept_mutex_held会被置1,
- if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) {
- return;
- }
- if (ngx_accept_mutex_held) {
- //设置NGX_POST_EVENTS标志是为了在处理新连接时,将新的event放到
- //事件队列异步处理,而不是立刻处理(防止阻塞)
- flags |= NGX_POST_EVENTS;
- } else {
- //没获取到accept锁
- if (timer == NGX_TIMER_INFINITE
- || timer > ngx_accept_mutex_delay)
- {
- timer = ngx_accept_mutex_delay;
- }
- }
- }
- }
- delta = ngx_current_msec;
- //这里是一个函数指针,指向当前使用IO模块中的事件处理函数,等待事件到来的超时时间是timer
- (void) ngx_process_events(cycle, timer, flags);
- delta = ngx_current_msec - delta;
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "timer delta: %M", delta);
- //处理accept event队列中事件
- ngx_event_process_posted(cycle, &ngx_posted_accept_events);
- //如果持有accept锁,就释放,避免一个进程长期持有该锁。在大都是长连接的情况下,这回导致
- //各个worker负载的严重不均匀
- if (ngx_accept_mutex_held) {
- ngx_shmtx_unlock(&ngx_accept_mutex);
- }
- //检查是否有超时(过期)的事件,如果有进行处理
- if (delta) {
- ngx_event_expire_timers();
- }
- //处理普通event队列中的事件
- ngx_event_process_posted(cycle, &ngx_posted_events);
- }
- //////////// nginx/src/event/ngx_event_accept.c /////////////
- //接受新的连接
- void ngx_event_accept(ngx_event_t *ev)
- {
- ......
- //如果剩余的空闲连接数小于连接池总数的1/8,下次执行ngx_process_events_and_timers时
- //就不再竞争accept锁
- ngx_accept_disabled = ngx_cycle->connection_n / 8
- - ngx_cycle->free_connection_n;
- ......
- //从连接池中取出一个连接并进行初始化
- c = ngx_get_connection(s, ev->log);
- ......
- //将新建的连接通过ngx_add_conn函数指针加入到IO复用函数的等待队列中
- if (ngx_add_conn && (ngx_event_flags & NGX_USE_EPOLL_EVENT) == 0) {
- if (ngx_add_conn(c) == NGX_ERROR) {
- ngx_close_accepted_connection(c);
- return;
- }
- }
- log->data = NULL;
- log->handler = NULL;
- //ls对应的handler是在ngx_http_add_listening函数中将ngx_http_init_connection
- //函数赋值给了handler
- ls->handler(c);
- ......
- }
- //////////// nginx/src/event/modules/ngx_epoll_module.c /////////////
- //epoll模块事件处理函数
- static ngx_int_t ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
- {
- ......
- //等待新连接(最多阻塞timer时长)
- events = epoll_wait(ep, event_list, (int) nevents, timer);
- ......
- //如果设置了NGX_POST_EVENTS就说明当前持有accept锁,应当将新事件放到队列中,尽快返回
- if (flags & NGX_POST_EVENTS) {
- queue = rev->accept ? &ngx_posted_accept_events
- : &ngx_posted_events;
- ngx_post_event(rev, queue);
- } else {
- //没有持有accept锁,可以同步执行事件处理函数
- //rev->handler在ngx_http_init_connection函数中被赋值为ngx_http_wait_request_handler
- rev->handler(rev);
- }
- .......
- }
来源: http://www.cnblogs.com/sxhlinux/p/6785551.html