设为首页 加入收藏

TOP

Libevent浅析(二)
2017-10-11 15:46:02 】 浏览:8145
Tags:Libevent 浅析
量*/
int event_count; /**< counts number of total events */ int event_count_active; /**< counts number of active events */ /* 是否执行完活动事件队列上的剩余任务之后就退出事件循环 */ int event_gotterm; /**< Set to terminate loop once done * processing events. */ /* 是否立即退出事件循环,而不管是否还有任务需要处理 */ int event_break; /**< Set to exit loop immediately */ /* 活动事件队列数组。索引越小的队列,优先级越高。高优先级的活动事件队列中的事件处理器将被优先处理*/ struct event_list **activequeues; /* 活动事件队列数组的大小,即该event_base一共有nactivequeues个不同优先级的活动事件队列*/ int nactivequeues; /*是否应该启动一个新的事件循环*/ int event_continue; //目前正在处理的活动事件队列的优先级 int event_running_priority; //事件循环是否已经启动 int running_loop; /** Deferred callback management: a list of deferred callbacks to * run active the active events. */ TAILQ_HEAD (deferred_cb_list, deferred_cb) deferred_cb_list; //文件描述符和IO事件之间的映射关系表 struct event_io_map io; /*信号值和信号事件之间的映射关系表*/ struct event_signal_map sigmap; /*注册时间队列,存放IO事件处理器和信号事件处理器*/ struct event_list eventqueue; /*时间堆*/ struct min_heap timeheap; //系统管理时间的一些成员 struct timeva l event_tv; struct timeva l tv_cache; }; 其中:
  • evsel和evbase这两个字段的额设置可能会让人迷惑,可以将其看作是类和静态函数的关系,比如添加事件时的调用行为:evsel->add(evbase, ev),实际上执行操作的是evbase,这相当于class::add(instance, ev),instance就是class的一个实例。evsel指向全局变量static const struct eventop *eventops[]中的一个。eventops[]包含了select,poll,kequeue和epoll等等其中的若干个全局实例对象。evbase实际上是一个eventop实例对象。
  • eventop结构体,是一系列的函数指针,定义如下:

    struct eventop{
        const char* name;
        void *(*init)(struct event_base *);   //初始化
        int (*add)(void *, struct event *);  //注册事件
        int (*del)(void *, struct event *);  //删除事件
        int (*dispatch)(struct event_base*, void *, struct timeva l *); //事件分发
        void (*dealloc)(struct event_base*, void *);  //注销,释放资源
        //set if we need to reinitialize the event_base
        int need_reinit;
    };

    在libevent中,每个IO事件分发机制的实现都必须提供这五个函数接口。

  • 事件主循环主要是通过event_base_loop()函数来完成的。其代码如下:

    int event_base_loop(struct event_base *base, int flags){
        const struct eventop *evsel = base->evsel;
        void *evbase = base->evbase;
        struct timeva l tv;
        struct timeva l *tv_p;
        int res, done;
    
        //清空时间缓存
        base->tv_cache.tv_sec = 0;
    
        //evsignal_base是全局变量,在处理signal时,用于指明signal所属的event_base实例
        if(base->sig.ev_signal_added)
            evsignal_base = base;
    
        done = 0;
    
        //事件主循环
        while(!done){
            //查看是否需要跳出循环,程序可以调用event_loopexit_cb()设置event_gotterm标记
            //调用event_base_loopbreak设置event_break标志
            if(base->event_gotterm){
                base->event_gotterm = 0;
                break;
            }
    
            if(base->event_break){
                base->event_break = 0;
                break;
            }
    
            //you cannot use this interface for multi-threaded apps
            while(event_gotsig){
                event_gotsig = 0;
                if(event_sigcb){
                    res = (*event_sigcb)();
                    if(res == -1){
                        errno = EINTR;
                        return -1;
                    }
                }
            }
    
            //校正系统时间,如果系统使用的是非MONOTONIC时间,用户可能会向后调整了系统时间
            //在timeout_correct函数中,比较last wait time和当前事件,如果
            //当前时间 < last wait time
            //表明时间有问题,这需要更新timer_heap中所有定时事件的超时时间
            timeout_correct(base, &tv);
    
    
            //根据time heap中事件的最小超时时间,计算系统IO demultiplexer的最大等待时间
            tp_p = &tv;
            if(!base->event_count_active && !(flags & EVLOOP_NONBLOCK)){
                timeout_next(base, &tv_p);
            }
            else{
                //依然有未处理的就绪时间,就让IO demultiplexer立即返回,不必等待
                //下面会提到,在libevent中,低优先级的就绪事件可能不能立即被处理
                evutil_timerclear(&tv);
            }
    
            //如果当前没有注册事件,就退出
            if(!event_haveevents(base)){
                event_debug("%s: no events registered.", __func__);
                return 1;
    
  • 首页 上一页 1 2 3 下一页 尾页 2/3/3
    】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
    上一篇2632 非常好友 下一篇2851 菜菜买气球

    最新文章

    热门文章

    Hot 文章

    Python

    C 语言

    C++基础

    大数据基础

    linux编程基础

    C/C++面试题目