libevent中的几个数据结构

Posted randyniu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了libevent中的几个数据结构相关的知识,希望对你有一定的参考价值。

struct event {
    TAILQ_ENTRY (event) ev_next;                //读写和信号事件在事件链表的位置
    TAILQ_ENTRY (event) ev_active_next;            //就绪事件在就绪链表的位置
    TAILQ_ENTRY (event) ev_signal_next;            //信号事件在信号链表的位置
    unsigned int min_heap_idx;                    //定时时间在小根堆的位置
 
    struct event_base *ev_base;                    //每个事件关联的事件框架
 
    int ev_fd;                                    //读写事件为文件描述符,信号事件为信号值,定时事件设置为-1
    short ev_events;                            //事件的类型
    short ev_ncalls;                            //回调函数要执行的次数
    short *ev_pncalls;                            //一般指向上面那个变量,用来中断回调函数的执行用
 
    struct timeval ev_timeout;                     //定时事件的定时结束时间
 
    int ev_pri;                                    //事件的优先级
 
    void (*ev_callback)(int, short, void *arg); //回调函数
    void *ev_arg;                                //用作回调函数的第三个参数
 
    int ev_res;                                    //当前激发(就绪)的事件
    int ev_flags;                                //当前所在的链表类型
};
 
struct event_base {
    const struct eventop *evsel;                   //统一事件的机制,比如在linux下它就会选择epoll机制
    void *evbase;                                //如果上面选择了epoll机制,那么这个其实就是epoll.c里面的epollop类
    int event_count;                            //总事件的个数
    int event_count_active;                        //激活事件的个数
 
    int event_gotterm;                            //设置下轮终止event_base_loop的循环Set to terminate loop
    int event_break;                            //设置立即终止event_base_loop的循环 Set to terminate loop immediately
 
    /* active event management */
    struct event_list **activequeues;           //具有优先级(因为双指针)的就绪事件链表
    int nactivequeues;                            //最大优先级,其实就是优先级的等级范围
 
    /* signal handling info */
    struct evsignal_info sig;                    //用来管理信号事件用的,有一系列操作在signal.c
 
    struct event_list eventqueue;                //注册后信号事件或者读写事件所在的事件链表
    struct timeval event_tv;                    //用作时间修正
 
    struct min_heap timeheap;                    //存定时事件的小根堆
 
    struct timeval tv_cache;                    //保存现在的时间,其实直接用系统函数就可以得到当前时间,但是费时,
                                                //所以就用这个来缓存下当前时间,就不用一直用系统调用了。
};

struct evepoll {
    struct event *evread;
    struct event *evwrite;
};
struct epollop {
    struct evepoll *fds;                        //因为我们用的是epoll_wait来统一事件,所以需要一个文件描述符对应一个epoll_event和event,
                                                //这个链表作用是用来关联epoll_event结构的,关联后用epoll_wait后可得到第二个参数,
                                                //即epoll_event*链表,后面可以对对应的event做处理,
    比如插入就绪链表等动作。
    int nfds;                                    //最大文件描述符值
    struct epoll_event *events;                    //跟evepoll 关联的事件链表
    int nevents;                                //用epoll_wait得到的第三个参数,即events的大小
    int epfd;                                    //epoll_create得到的管理文件描述符
};
 
struct evsignal_info {
    struct event ev_signal;                                            
    int ev_signal_pair[2];                        //注册的一对socket
    int ev_signal_added;                        //是否已注册信号
    volatile sig_atomic_t evsignal_caught;        //是否有信号触发
    struct event_list evsigevents[NSIG];        //信号链表,所有注册的信号都在此链表
    sig_atomic_t evsigcaught[NSIG];                //对应信号的触发次数
#ifdef HAVE_SIGACTION
    struct sigaction **sh_old;                    //这个其实是用来恢复注册信号的回调函数的,比如你在程序另一边也注册了这个信号的回调函数,
                                                //但是这边又用libevent注册了,那么在这个框架结束后它会帮你恢复之前的回调函数。
#else
    ev_sighandler_t **sh_old;
#endif
    int sh_old_max;                              //能恢复信号的回调函数的最大数量
}

 

以上是关于libevent中的几个数据结构的主要内容,如果未能解决你的问题,请参考以下文章

浅谈libevent的使用--事件和数据缓冲

Libevent + Comet(长轮询/Http-Stream)

片段问题中的 NullPointerException

使 PHP 代码更加简洁的几个小技巧

IO事件

使用 libev 的套接字