事件驱动函数
事件驱动是nginx设计的核心,linux平台下,nginx会优先使用epoll进行事件处理。main—>master_process_cycle—>ngx_start_worker_process—>ngx_worker_process_cycle—>ngx_worker_process_init,ngx_process_events_and_timers。master进程中创建worker进程,之后在ngx_worker_process_cycle函数中初始化,并打开socketpair,加入epoll中。随后进入ngx_process_events_and_timers函数,等待http连接请求。nginx作为web服务器,性能要求很高,对最耗时的IO进行异步处理。注册到epoll上,作为一个个事件待触发。定义的事件处理函数如下:
ngx_event_module_t ngx_epoll_module_ctx = {
&epoll_name,
ngx_epoll_create_conf, /* create configuration */
ngx_epoll_init_conf, /* init configuration */
{
ngx_epoll_add_event, /* add an event */
ngx_epoll_del_event, /* delete an event */
ngx_epoll_add_event, /* enable an event */
ngx_epoll_del_event, /* disable an event */
ngx_epoll_add_connection, /* add an connection */
ngx_epoll_del_connection, /* delete an connection */
NULL, /* process the changes */
ngx_epoll_process_events, /* process the events */
ngx_epoll_init, /* init the events */
ngx_epoll_done, /* done the events */
}
};
等待连接请求
worker进程启动后调用ngx_worker_process_init,初始化连接,监听80端口,之后不断调用ngx_process_events_and_timers 函数,等待http连接请求。
ngx_process_events_and_timers
if (ngx_use_accept_mutex) {
if (ngx_accept_disabled > 0) {
ngx_accept_disabled--;
//多进程情况下通过共享内存的互斥锁,同一时间只允许一个进程得到访问,解决惊群问题。
} else {
//得到互斥锁后,将对应端口的(Http默认为80端口)事件加入epoll,等待客户端连接请求,触发IO事件。
if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) {
return;
}
//多进程情况下,使用NGX_POST_EVENTS,将触发的事件放入队列中,而不是里面触发IO的回调函数
if (ngx_accept_mutex_held) {
flags |= NGX_POST_EVENTS;
} else {
if (timer == NGX_TIMER_INFINITE
|| timer > ngx_accept_mutex_delay)
{
timer = ngx_accept_mutex_delay;
}
}
}
}
//调用的是ngx_epoll_process_events,执行的是epoll_wait,当有事件被触发时,将执行IO回调函数,或者将被触发的IO事件添加到链表。
(void) ngx_process_events(cycle, timer, flags);
//依次访问被触发的IO事件,执行回调
if (ngx_posted_accept_events) {
ngx_event_process_posted(cycle, &ngx_posted_accept_events);
}
//释放共享互斥锁
if (ngx_accept_mutex_held) {
ngx_shmtx_unlock(&ngx_accept_mutex);
}
//处理超时事件
if (delta) {
ngx_event_expire_timers();
}
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->