【Linux】【网络】Reactor补充+Libevent
1. 组件与类解析
1.1 句柄
IO框架库要处理的对象,即IO事件、信号和定时事件,统一称为事件源。一个事件源通常和一个句柄绑定在一起.句柄的作用是,当内核检测到就绪事件时,它将通过句柄来通知应用程序这一事件。在LINUX环境下,I/0事件对应的句柄是文件描述符,信号事件对应的句柄就是信号值。
1.2 Reactor(反应器)
- 职责:事件循环的核心,管理和调度事件的监听、分发和处理。
- 对应 Libevent:
event_base
。 - 关键函数:
- handle_events():启动事件循环并处理事件,Libevent 对应函数:
event_base_dispatch(base)
。 - register_handler():注册事件处理器,Libevent 对应函数:
event_add(ev, timeout)
。 - remove_handler():移除事件处理器,Libevent 对应函数:
event_del(ev)
。
- handle_events():启动事件循环并处理事件,Libevent 对应函数:
1.3 EventDemultiplexer(事件多路分发器)
- 职责:封装底层 I/O 多路复用机制(如
select
、poll
、epoll
),统一接口监听事件的就绪状态。 - 对应 Libevent 实现:Libevent 内部使用
epoll
(Linux)和kqueue
(BSD)等多路复用机制。 - 关键函数:
- register_event():注册事件类型,Libevent 内部在创建事件时通过
event_new()
来设置事件类型。 - remove_event():移除事件,Libevent 对应函数:
event_del()
。 - demultiplex():检测就绪事件,Libevent 内部通过
epoll_wait
或kqueue
等进行事件检测。
- register_event():注册事件类型,Libevent 内部在创建事件时通过
1.4 EventHandler(事件处理器)
- 职责:定义事件处理的抽象接口,具体事件处理器需要实现该接口。
- 对应 Libevent:
event
- 对应 Libevent 实现:回调函数。
- 关键函数:
- get_handle():获取事件关联的句柄,Libevent 中对应
event
结构的ev_fd
字段。 - handle_event():处理事件的逻辑,Libevent 中对应用户自定义的回调函数,如
read_cb(evutil_socket_t fd, short events, void *arg)
。
- get_handle():获取事件关联的句柄,Libevent 中对应
1.5 ConcreteEventHandler(具体事件处理器)
- 职责:实现
EventHandler
接口,处理具体业务逻辑。 - 对应 Libevent 示例:回调函数(例如
read_cb
)。
完整流程示例
// 1. 初始化 Reactor(event_base)
struct event_base *base = event_base_new();// 2. 创建事件处理器(如监听套接字)
evutil_socket_t listen_fd = socket(...);
struct event *listen_event = event_new(base, listen_fd, EV_READ | EV_PERSIST, accept_cb, base);// 3. 注册事件处理器
event_add(listen_event, NULL);// 4. 启动事件循环
event_base_dispatch(base);// 5. 事件触发时调用 handle_event(accept_cb)
void accept_cb(evutil_socket_t fd, short events, void *arg) {struct event_base *base = arg;evutil_socket_t client_fd = accept(fd, ...);// 创建新的 bufferevent 处理客户端数据struct bufferevent *bev = bufferevent_socket_new(base, client_fd, BEV_OPT_CLOSE_ON_FREE);bufferevent_setcb(bev, read_cb, NULL, error_cb, NULL);bufferevent_enable(bev, EV_READ);
}// 6. 具体数据处理(ConcreteEventHandler::handle_event)
void read_cb(struct bufferevent *bev, void *arg) {char buf[1024];bufferevent_read(bev, buf, sizeof(buf));// 处理数据...
}
5. 总结
- Reactor(反应器) 是事件驱动模型的核心,Libevent 中的
event_base
对应该角色,负责调度事件循环。 - EventDemultiplexer(事件多路分发器) 底层封装多路复用机制(如
epoll
),用于检测事件是否就绪。 - EventHandler(事件处理器) 和 ConcreteEventHandler 是处理事件的抽象和具体实现,Libevent 中对应回调函数的处理逻辑。