libevent学习笔记
来源:互联网 发布:jsp页面连接数据库 编辑:程序博客网 时间:2024/05/22 13:04
先大概整理一下,再慢慢看
libevent:
事件驱动(event-driven),高性能;
轻量级,专注于网络,不如 ACE 那么臃肿庞大;
源代码相当精炼、易读;
跨平台,支持 Windows、 Linux、 *BSD 和 Mac Os;
支持多种 I/O 多路复用技术, epoll、 poll、 dev/poll、 select 和 kqueue 等;
支持 I/O,定时器和信号等事件;
注册事件优先级;
事件驱动设计模式——reactor模式:
应用程序需要提供相应的接口并注册到 Reactor 上,如果相应的时间发生, Reactor 将主动调用
应用程序注册的接口,这些接口又称为“回调函数”。
Reactor 模式的优点:
1)响应快,不必为单个同步时间所阻塞,虽然 Reactor 本身依然是同步的;
2)编程相对简单,可以最大程度的避免复杂的多线程及同步问题,并且避免了多线程/
进程的切换开销;
3)可扩展性,可以方便的通过增加 Reactor 实例个数来充分利用 CPU 资源;
4)可复用性, reactor 框架本身与具体事件处理逻辑无关,具有很高的复用性;
Reactor 模式框架
使用 Reactor 模型,必备的几个组件:事件源、 Reactor 框架、多路复用机制和事件处理程序
1) 事件源 Linux 上是文件描述符
2) event demultiplexer——事件多路分发机制 由操作系统提供的 I/O 多路复用机制,比如 select 和 epoll。
3) Reactor——反应器
Reactor,是事件管理的接口,内部使用 event demultiplexer 注册、注销事件;并运行事
件循环,当有事件进入“就绪”状态时,调用注册事件的回调函数处理事件。对应到 libevent 中,就是 event_base 结构体。
4) Event Handler——事件处理程序
事件处理程序提供了一组接口,每个接口对应了一种类型的事件,供 Reactor 在相应的
事件发生时调用,执行相应的事件处理。通常它会绑定一个有效的句柄。
对应到 libevent 中,就是 event 结构体。
使用 libevnet 的基本流程:
1)首先初始化 libevent 库,并保存返回的指针
struct event_base * base = event_init();实际上这一步相当于初始化一个 Reactor 实例;
在初始化 libevent 后,就可以注册事件了。
2)初始化事件 event,设置回调函数和关注的事件event_set 的函数原型是: void event_set(struct event *ev, int fd, short event, void (*cb)(int,short, void *), void *arg)ev:执行要初始化的 event 对象;fd:该 event 绑定的“句柄”,对于信号事件,它就是关注的信号;event:在该 fd 上关注的事件类型,它可以是 EV_READ, EV_WRITE, EV_SIGNAL;cb:这是一个函数指针,当 fd 上的事件 event 发生时,调用该函数执行处理,它有三个参数,调用时由 event_base 负责传入,按顺序,实际上就是 event_set 时的 fd, event 和 arg;arg:传递给 cb 函数指针的参数;3)设置 event 从属的 event_base event_base_set(base, &ev);这一步相当于指明 event 要注册到哪个 event_base 实例上;4)是正式的添加事件的时候了event_add(&ev, timeout); 基本信息都已设置完成,只要简单的调用 event_add()函数即可完成,其中 timeout 是定时值;这一步相当于调用 Reactor::register_handler()函数注册事件。5)程序进入无限循环,等待就绪事件并执行事件处理 event_base_dispatch(base);实例代码:
struct event ev; struct timeval tv; void time_cb(int fd, short event, void *argc) { printf("timer wakeup\n"); event_add(&ev, &tv); // reschedule timer } int main() { struct event_base *base = event_init(); tv.tv_sec = 10; // 10s period tv.tv_usec = 0; evtimer_set(&ev, time_cb, NULL); event_add(&ev, &tv); event_base_dispatch(base); }
事件处理流程:
1) 首先应用程序准备并初始化 event,设置好事件类型和回调函数;这对应于前面第步骤2 和 3;
2) 向 libevent 添加该事件 event。对于定时事件, libevent 使用一个小根堆管理, key 为超
时时间;对于 Signal 和 I/O 事件, libevent 将其放入到等待链表(wait list)中,这是一
个双向链表结构;
3) 程序调用 event_base_dispatch()系列函数进入无限循环,等待事件,以 select()函数为例;
每次循环前 libevent 会检查定时事件的最小超时时间 tv,根据 tv 设置 select()的最大等
待时间,以便于后面及时处理超时事件;
当 select()返回后,首先检查超时事件,然后检查 I/O 事件;
Libevent 将所有的就绪事件,放入到激活链表中;
然后对激活链表中的事件,调用事件的回调函数执行事件处理;
- libevent学习笔记
- Libevent库学习笔记
- 学习笔记--libevent min_heap
- libevent学习笔记
- libevent学习笔记 -evbuffer
- Libevent学习笔记
- libevent 学习笔记 一
- libevent 学习笔记 二
- libevent 学习笔记 三
- libevent 学习笔记 四
- libevent 学习笔记 一
- libevent学习笔记
- libevent学习笔记
- libevent学习笔记 -1 设置 Libevent库
- libevent学习笔记1:牛刀小试
- libevent学习笔记 一、基础知识
- libevent学习笔记--setvbuf()函数
- Libevent源代码学习笔记1
- C++ String 简单总结
- ROS会议 ROSCon 2017
- CSS3动画特效
- synchronize用法
- zookeeper的linux安装
- libevent学习笔记
- Uncaught TypeError: Cannot assign to read only property 'exports' of object '#<Object>'
- C++ primer阅读笔记----------表达式
- Oracle 遭遇ORA-02064 :不支持分布式操作 解决
- 【去哪儿】寻找Coder
- 设计模式:Decorator模式(即装饰者模式)------------个人理解
- win10下用tomcat配置负载均衡
- 如何在FPGA中进行分频
- Maximum Average Subarray I