Chinaunix首页 | 论坛 | 博客
  • 博客访问: 96004
  • 博文数量: 31
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 380
  • 用 户 组: 普通用户
  • 注册时间: 2014-02-24 22:04
文章分类

全部博文(31)

文章存档

2014年(31)

我的朋友

分类: C/C++

2014-06-04 14:28:05


在(从Time-test.c中窥探libevent执行步骤 )中已谈到,超时事件的触发流程主要分为以下几步
(1) 定义一个超时事件ev
(2) 调用event_init()创建一个eventbase
(3) 调用evtimer_set()设置ev的数据成员,包括回调函数
(4) 调用event_add()绑定ev到eventbase
(5) 调用event_dispatch()等待事件被触发

在第二步“调用event_init()创建一个eventbase”中,
(1) event_init()调用event_base_new()函数创建一个eventbase对象,并把该eventbase对应赋给全局的current_base对象
(2) event_base_new()函数首先为eventbase对象分配空间,
    并且设置eventbase中的event_tv,
    初始化timeheap小根堆头节点,
    初始化事件链表的头节点eventqueue,
    绑定evsel到指定IO多路复用技术,并调用evsel->init函数,执行具体的操作,把执行结果放入eventbase对象的evbase变量中
    调用event_base_priority_init函数设置nactivequeue,并为activequeues链表分配空间


在第三步“调用evtimer_set()设置ev的数据成员,包括回调函数”中,
(1) evtimer_set宏调用的是函数event_set(ev, -1, 0, cb, arg),0指示ev属于timeout事件,-1标识timeout事件的文件描述符。
(2) event_set()函数初始化ev,并设定ev中的数据成员与回调函数,绑定ev到current_base
(3) 调用min_heap_elem_init初始化ev在小根堆中的index
(4) 设置ev的默认优先级,并放入到eventbase中的eventqueue[i]链表中,i标识该ev的优先级

第四步“调用event_add()绑定ev到eventbase”中
(1) event_add()的两个参数中,一个ev,一个是tv,tv指定了该ev的超时间隔
(2) event_add()函数针对超时事件ev,首先设定ev的数据成员ev_timeout,该成员被赋值为现在时间now与指定超时时间间隔tv之和
(3) 调用event_queue_insert()函数把ev插入到EVLIST_TIMEOUT链表中,这个动作实际上是把ev放入到小根堆中,并修改ev的数据成员ev_flags,该成员记录ev在哪个链表之中。
(4) 在event_add()函数中,因为ev是超时事件,所以没有执行evsel->add()函数,该函数是把ev绑定到IO多路复用技术的链表中。如果事件ev不是属于EV_TIMEOUT,而是EV_ERAD,或者EV_WRITE,或者EV_SIGNAL,则会调用add()函数,绑定ev到IO多路复用技术的链表中。


第五步“调用event_dispatch()等待事件被触发”中
(1) event_dispatch()函数实际上调用的是event_base_loop()函数
(2) event_base_loop()函数核心是其中的死循环,在该循环中
    首先检查是否系统时间是否被修改,若被修改,则修改eventbase中的event_tv与tv_cache
    计算当前时间now与小根堆中的头节点的超时时间ev_timeout之差tv_p
    把tv_p作为evsel->dispatch的超时参数传入,dispatch函数检查是否有相应的设备准备就。由于当前情况是处理超时事件,超时事件监听的设备描述符是-1,所以该函数不会做任何的事情。并且evsel->dispatch恰好会在指定超时时间tv_p之后返回
    调用timeout_process()函数,这时小根堆上的第一个元素一定超时了,把第一个元素ev放入到active活动链表中
    调用event_process_active()函数,处理活动链表中的事件
    

这样,一个超时事件就处理完毕了,在Time-test.c中,可以看到程序在回调函数中有再次调用了event_add(),重新把ev绑定到eventbase上,并设定超时间隔2秒,这样,一段时间过后,该ev就会被再次触发。这样就实现了每隔2秒,执行特定函数的功能了。





阅读(2526) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~