前言
重新梳理一遍muduo网络库的类与知识点。
Channel、EPollPoller与EventLoop类是muduo库最重要的基础, 他们三类为一体,在底层负责事件循环。EventLoop包含Channel,Poller,EventLoop负责轮询访问Poller,得到激活Channel列表,使Channel自己根据自身情况调用相应回调。
一、Channel类
Channel类是对文件描述符(fd)以及其相关事件的封装。
在TCP网络编程中,想要IO多路复用监听某个文件描述符,就要把这个fd和该fd感兴趣的事件通过epoll_ctl注册到IO多路复用模块上。当事件监听器监听到该fd发生了某个事件。事件监听器返回 [发生事件的fd集合]以及[每个fd都发生了什么事件]
Channel类则封装了一个 [fd] 和这个 [fd感兴趣事件] 以及事件监听器监听到 [该fd实际发生的事件]。Channel类还提供了设置该fd的感兴趣事件,以及将该fd及其感兴趣事件注册到事件监听器或从事件监听器上移除,以及保存了该fd的每种事件对应的处理函数
1、主要成员变量以及函数
以下是对Channel
类的各个成员变量和成员函数的解析:
-
成员变量:
-
loop_
:指向所属的事件循环(EventLoop
)对象的指针。 -
fd_
:表示该Channel
对象关联的文件描述符。 -
events_
:表示该Channel
对象感兴趣的事件类型(如EPOLLIN
、EPOLLOUT
等)。 -
revents_
:表示由事件分发器(Poller
)返回的具体发生的事件类型。 -
index_
:用于记录该Channel
对象在事件分发器中的位置或状态。 -
readCallback_
、writeCallback_
、closeCallback_
、errorCallback_
:各种回调函数,用于处理不同事件的回调操作。
-
-
成员函数:
-
构造函数和析构函数:初始化和销毁
Channel
对象。 -
update
:在Channel
对象所属的事件循环中,通过调用事件分发器的相应方法,注册或更新文件描述符的事件类型。 -
remove
:在Channel
对象所属的事件循环中,将当前的Channel
对象从事件分发器中移除。 -
handleEvent
:处理文件描述符上发生的具体事件,根据事件类型调用相应的回调函数。 -
handleEventWithGuard
:在保护锁的作用下执行处理事件的具体逻辑。
-
2、实现原理
void setReadCallback(ReadEventCallback cb) {
read_callback_ = std::move(cb);}
void setWriteCallback(Eventcallback cb) {
write_callback_ = std::move(cb);}
void setCloseCallback(EventCallback cb) {
close_callback_ = std::move(cb);}
void setErrorCallback(EventCallback cb) {
error_callback_ = std::move(cb);}
一个文件描述符会发生可读、可写、关闭、错误事件。当发生这些事件后,就需要调用相应的处理函数来处理。外部通过调用上面这四个函数可以将事件处理函数放进Channel类中,当需要调用的时候就可以直接拿出来调用了。
// 设置fd相应的事件状态
void enableReading() {
events_ |= kReadEvent; update(); }
void disableReading() {
events_ &= ~kReadEvent; update(); }
void enableWriting() {
events_ |= kWriteEvent; update(); }
void disableWriting() {
events_ &= ~kWriteEvent; update(); }
void disableAll() {
events_ = kNoneEvent; update(); }
void