nginx epoll详解

本文详细探讨了nginx如何在Linux上利用epoll实现高效事件处理。介绍了ngx_event_t结构体及其成员,以及ngx_epoll_module如何封装epoll机制。重点分析了ngx_epoll_init、ngx_epoll_add_event、ngx_epoll_del_event等关键函数,揭示了nginx在启动过程中worker进程如何初始化epoll事件处理。
摘要由CSDN通过智能技术生成

nginx epoll 事件模型


    nginx做为一个异步高效的事件驱动型web服务器,在linux平台中当系统支持epoll时nginx默认采用epoll来高效的处理事件。nginx中使用ngx_event_t结构来表示一个事件,先介绍下ngx_event_t结构体中成员的含义:

struct ngx_event_s {
    void            *data;  //与事件关联的对象,常指向事件所在的ngx_connection_t连接对象

    unsigned         write:1; //可写标识位,1表示对应的tcp连接是可写的

    unsigned         accept:1;// 1表示对应的连接是处于监听状态的连接,即可接收新的连接

    /* used to detect the stale events in kqueue, rtsig, and epoll */
    unsigned         instance:1; //可来区分事件是否已过期

    /*
     * the event was passed or would be passed to a kernel;
     * in aio mode - operation was posted.
     */
    unsigned         active:1;// 1表示事件活跃,即事件已添加到epoll中

    unsigned         disabled:1;//epoll中不使用该标识位

    /* the ready event; in aio mode 0 means that no operation can be posted */
    unsigned         ready:1; //事件已就绪(即可读或可写)

    unsigned         oneshot:1;//epoll不使用该标识位

    /* aio operation is complete */
    unsigned         complete:1;//aio中使用,表示 事件对应的aio异步操作已完成(io_getevents函数已成功返回)

    unsigned         eof:1;// 1表示当前处理的字符流已完成,如调用recv读取连接数据时返回0,此时置该标识位为1
    unsigned         error:1;// 1表示事件处理过程中发生错误

    unsigned         timedout:1;   //事件是否超时,1:表示超时。超时后事件对应的请求不需再被处理(对于http模块来说事件超时后直接关闭请求)
    unsigned         timer_set:1; //为1时表示这个事件在定时器中

    unsigned         delayed:1;// 1表示 需延迟处理该事件,常用于限速功能中

    unsigned         deferred_accept:1;//延迟接收接连,即当连接中收到对象发送的数据后才真正建立连接

    /* the pending eof reported by kqueue, epoll or in aio chain operation */
    unsigned         pending_eof:1;// 1表示TCP连接对向关闭读端,即epoll返回EPOLLRDHUP

#if !(NGX_THREADS)
    unsigned         posted_ready:1;//该标识位在1.5.5版本源码中只在ngx_epoll_process_events函数中有置位,其它地方并没有用到
#endif

#if (NGX_WIN32)
    /* setsockopt(SO_UPDATE_ACCEPT_CONTEXT) was successful */
    unsigned         accept_context_updated:1;
#endif

#if (NGX_HAVE_KQUEUE)
    unsigned         kq_vnode:1;

    /* the pending errno reported by kqueue */
    int              kq_errno;
#endif

    /*
     * kqueue only:
     *   accept:     number of sockets that wait to be accepted
     *   read:       bytes to read when event is ready
     *               or lowat when event is set with NGX_LOWAT_EVENT flag
     *   write:      available space in buffer when event is ready
     *               or lowat when event is set with NGX_LOWAT_EVENT flag
     *
     * iocp: TODO
     *
     * otherwise:
     *   accept:     1 if accept many, 0 otherwise
     */

#if (NGX_HAVE_KQUEUE) || (NGX_HAVE_IOCP)
    int              available;
#else
    unsigned         available:1;// 1表示每次调用accept时尽可能多的接收TCP连接,与multi_accept配置项对应
#endif

    ngx_event_handler_pt  handler; // 事件产生后的回调函数句柄


#if (NGX_HAVE_AIO)

#if (NGX_HAVE_IOCP)
    ngx_event_ovlp_t ovlp;
#else
    struct aiocb     aiocb;
#endif

#endif

    ngx_uint_t       index; //epoll中不使用

    ngx_log_t       *log; //ngx_log_t对象

    ngx_rbtree_node_t   timer;  

    unsigned         closed:1; // 1表示事件已关闭

    /* to test on worker exit */
    unsigned         channel:1;// 只在ngx_add_channel_event函数中有置位,其它地方没用到
    unsigned         resolver:1; // resolver功能中使用?

#if (NGX_THREADS)

    unsigned         locked:1;

    unsigned         posted_ready:1;
    unsigned         posted_timedout:1;
    unsigned         posted_eof:1;

#if (NGX_HAVE_KQUEUE)
    /* the pending errno reported by kqueue */
    int              posted_errno;
#endif

#if (NGX_HAVE_KQUEUE) || (NGX_HAVE_IOCP)
    int              posted_available;
#else
    unsigned         posted_available:1;
#endif

    ngx_atomic_t    *lock;
    ngx_atomic_t    *own_lock;

#endif

    /* the links of the posted queue */
    ngx_event_t     *next;
    ngx_event_t    **prev;


#if 0

 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值