看了这么多天后对libevent的理解
很详细的看了一下相关的源码和博客,还是记不住具体怎么实现的,还是先把整体框架给写出来吧。
首先,libevent是事件驱动的,也就是event,因此,所有这些都是围绕event展开的。libevent的事件分为普通IO事件,超时事件,和信号事件。
这么多事件,应该怎么管理呢,这个时候event_base就出现了。
struct event_base* base = event_base_new();//创建一个管理event的event_base对象,这个结构体中包含了好多内容,比如后端IO复用的选择,激活事件的队列,已经添加的队列
//等等,反正后面需要用到管理的,都是在event_base中,对了,还有时间管理的小根堆,我是记不住有哪些,贼多。
有了这个管理者,接下来就可以构造事件了。
struct event* ev = event_new(base, fd, EV_READ|EV_PERSIST, cb, arg);
忘了说了,libevent是一个非阻塞的异步通讯模型,这是因为,你只需要把你监听的文件描述符(fd),已经关心的触发的事件(EV_READ|EV_PERSISE),同时如果事件发生之后应该怎么处理的回调函数(cb),在构建event的时候放到event中,那么接下来所有的事情都是由event_base来进行管理的调度,你就不用管了,对应的事件发生就会调用对应的回调函数。其实,本质上说,libevent仅仅是多了一层封装,如果之前你有使用过epool的经历,那么就会稍微容易理解一点,本质上,libevent也是调用系统的IO复用函数。
好了,到这里位置,事件已经构建出来了,这个时候就可以聊一些事件的状态了。
像刚刚创建好的event,还没有加入到event_base中,这些事件成为init事件,也就是初始化事件。
如果一个event加入到了event_base中,这些事件称为insereted事件,也就是已经插入事件。
如果一个event上面发了对应监控的事件,这些事件称为activate事件。就先说这几个事件吧,后面还会在合适的场合添加事件的类型。
接下来,就可以将event添加到event_base中了。
event_add(ev, NULL);
上面这行代码没有设置事件的超时时间,也就是会一直等待调用,直到对应的事件发生,才会进行返回。
接下来,就是event_base开始对这些事件进行监管了。
event_base_dispatch(base);//开始监管这些事件,里面实现是一个while循环
最后,需要做的就是释放base资源,因为这些内存资源都是从堆上申请的,因此需要手动进行资源的释放工作。
event_base_free(base);