libevent理解

libevent包括了事件管理,缓存管理,DNS,HTTP等,其中事件管理有I/O,SIG,TIME
目前的项目中利用了事件管理进行TIME的定时操作,通过网上资料的查阅对libevent有了一定了解,在此记录


libevent需要一个IO事件管理方法,事件管理就是当单个进程有多个事件时候,能否在适当的时机去处理发生的事件
IO多路复用技术可以在一个进程内处理多个IO事件,多个IO事件的处理,select和Epoll是经典的两种方法


介绍:
select是在用户层收集所有需要监控文件的集合fd_set,交给内核去遍历,有读或写状态就返回mask
有了mask,返回用户层,应用依次判断是哪个文件有了读写,再进行处理函数执行
由于读写状态的mask改变,所以需要将之前文件集合重新交给内核重复后面步骤


Epoll是在内核建立一个文件集合的文件描述符,这样只需要一次拷贝到内核
修改内核的文件描述符,添加或删除一个
内核按照文件描述符内的文件集合遍历,注册相应的callback(写进active链表),
每次有新状态改变只需要查询active链表即可


相同:遍历可以执行一次,可以无限执行,可以执行一段时间返回
区别:
一个进程所打开的FD(文件描述符)是有限制的,fd集合最大1024/2048;红黑树存放所有fd和信息等

内核拷贝所有fd;只需要向红黑树进行文件信息添加

有读写返回mask;有读写返回调用cb,红黑树上文件插入到就绪列表

应用程序遍历找对应执行程序;有确定信息执行到对应程序

一个文件红黑树存储,一个信息结构体,一个就绪链表

使用:
int select(int maxfd,fd_set *readset,fd_set *writeset,fd_set *exceptset,const struct timeval* timeout);


int epoll_create(int size);内核高速cache里红黑树
int epoll_ctl(int epfd,int op,int fd,struct epoll_event *event);附加结构体信息:callback,监听方式和fd
int epoll_wait(int epfd,struct epoll_event *events,int maxevents,int timeout);events存放已经active链表




libevent可以选择性利用IO复用的某项技术
eventops[]数组存放用到的所有方法的统一内容,函数指针实现多态,有初始化,添加,删除,分发,注销
在编译阶选择IO机制,base->evsel = eventops[i];
根究IO机制和base关联初始化,base->evbase = base->evsel->init(base);


libevent需要实现时间事件的管理
时间事件就是规定某个时间去做对应事情,linux有定时任务设置
不过我们使用上面的IO复用技术实现,上述遍历可以进行一段时间,没有IO则返回
可以分为两种情况:
没有IO事件,则返回时就是TIME事件就绪时
有IO事件,返回时,TIME事件经过了一定时间,减去该时间,重新赋值timeout
多个time事件,而我们只能设置一个,设置最小的就行了,需要对时间排序,每次IO返回重新赋值,删除最小的,或者集体减去一定时间




libevent需要实现SIG事件的管理
SIG信号当内核接到后会直接执行,我们需要内核将该信号发生通知进程,去执行应用程序
而IO复用可以监听IO状态,现在只需要把SIG发生转换为IO读写状态
方法: 创建一个socket对,当SIG发生时,内核去写socket,IO复用监听该socket
将内核接收到SIG后,动作改为evsignal_handler,累计次数,设置触发标记,重新注册,写socket


libevent有两个重要的结构体
event_base内有:IO复用选择,优先级,就绪链表,小根堆,event指针链表,其实是event事件处理的方法
event内有:事件在链表位置,回调函数,回调次数,状态注册或激活
event_set是设置event事件的回调函数,监听类型,fd号
event_add是添加链表或堆,往IO复用里面注册事件,添加fd
event_del是删除链表或堆,在IO复用里注销某fd




event_base是event的公共部分
event是将要注册或删除到链表或堆上的项目,对event的操作就是使用event_base的所有方法
event_base_loop是分发机制,检查到人一个event激活,插入到激活链表,执行callback


1. struct event {
2. TAILQ_ENTRY (event) ev_next;//io链表中位置
3. TAILQ_ENTRY (event) ev_active_next;//激活就绪双向链表
4. TAILQ_ENTRY (event) ev_signal_next;//signal链表位置
5. unsigned int min_heap_idx; /* for managing timeouts */
6. struct event_base *ev_base;//reactor实例
7. int ev_fd;//绑定的io或signal
8. short ev_events;//signal,time,io
9. short ev_ncalls;//调用回调函数的次数
10. short *ev_pncalls; /* Allows deletes in callback */
11. struct timeval ev_timeout;//
12. int ev_pri; /* smaller numbers are higher priority */
13. void (*ev_callback)(int, short, void *arg);//回调函数void (*ev_callback)(int fd, short events, void *arg)
14. void *ev_arg;//任意值
15. int ev_res; /* result passed to event callback 激活事件的类型 */
16. int ev_flags;//当前状态注册链表中,激活链表中等
17. };


每当有event变为就绪状态时候,转移到active event list里面去
event_base_set(base,ev) 进程中有多个libevent实例,需要设置event到某一个event_base
event_set(ev,fd,events,callback,arg)缺省的event_base为libevent的全局指针current_base




1. struct event_base {
2. const struct eventop *evsel;//每种io demultiplex机制提供函数接口,
//对自身的初始化,释放,对事件的注册,注销和分发
3. void *evbase;//实际上是一个evsel实例
4. int event_count; /* counts number of total events */
5. int event_count_active; /* counts number of active events */
6. int event_gotterm; /* Set to terminate loop */
7. int event_break; /* Set to terminate loop immediately */
8. /* active event management */
9. struct event_list **activequeues;//优先级二级指针
10. int nactivequeues;
11. /* signal handling info */
12. struct evsignal_info sig;//管理信号
13. struct event_list eventqueue;//保存所有注册event指针
14. struct timeval event_tv;
15. struct min_heap timeheap;
16. struct timeval tv_cache;
17. };


用到的c语言知识,链表,红黑树,最小堆,函数指针
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值