关于muduo实现的Reactor模式,有三个关键的类:
1.事件分发器类Channel
2.封装I/O复用的Poller (主要研究EpollPoller)
3.定时器接口类TimerQueue
事件循环EventLoop类实现了Reactor的基本模式。
1.事件分发类Channel
事件分发器Channel的数据成员如下:
//定义事件类型变量
static const int kNoneEvent; //无事件
static const int kReadEvent; //可读事件
static const int kWriteEvent; //可写事件
EventLoop *loop_; //channel所属的loop
const int fd_; //channel负责的文件描述符
int events_; //注册的事件
int revents_; //poller设置的就绪的事件
int index_; //被poller使用的下标
bool logHup_; //是否生成某些日志
boost::weak_ptr<void> tie_; //
bool tied_;
bool eventHandling_; //是否处于处理事件中
bool addedToLoop_;
ReadEventCallback readCallback_; //读事件回调
EventCallback writeCallback_; //写事件回调
EventCallback closeCallback_; //关闭事件回调
ReadEventCallback errorCallback_; //错误事件回调
其中EventCallback和ReadEventCallback的声明如下:
typedef boost::function<void()> EventCallback; //事件回调函数对象类型
typedef boost::function<void(Timestamp)> ReadEventCallback; //读事件回调函数对象类型
//处理事件
void handleEvent(Timestamp receiveTime);
//设置可读事件回调
void setReadCallback(const ReadEventCallback &cb)
{
readCallback_ = cb;
}
//设置可写事件回调
void setWriteCallback(const EventCallback &cb)
{
writeCallback_ = cb;
}
//设置关闭事件回调
void setCloseCallback(const EventCallback &cb)
{
closeCallback_ = cb;
}
//设置错误事件回调
void setErrorCallback(const EventCallback &cb)
{
errorCallback_ = cb;
}
void tie(const boost::shared_ptr<void>&);
//返回注册的事件
int events()const
{
return events_;
}
//设置就绪的事件
void set_revents(int revt)
{
revents_ = revt;
}
//判断是否注册的事件
bool isNoneEvent()const
{
return events_ == kNoneEvent;
}
//注册可读事件
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();
}
//是否注册可写事件
bool isWriting() const
{
return events_ & kWriteEvent;
}
//是否注册可读事件
bool isReading() const
{
return events_ & kReadEvent;
}
Channel的主要功能为管理各种注册给poller的套接字描述符及其上发生的事件,以及事件发生了调用事件的回调函数。
Channel的主要作用如下:
1.首先我们给定Channel所属的loop以及其要处理的fd
2.接着我们开始注册fd_上需要监听的事件,如果是常用事件(读写等)的话,我们可以直接调用接口enable***来注册对应fd上的事件,与之对应的是disable***用来销毁特定的事件
3.再然后我们通过set***Callback来事件发生时的回调
Channel完整代码及分析见此篇博客:
2.I/O复用类Poller
Poller类是个基类,它的定义如下:
class Poller : boost::noncopyable
{
public:
typedef std::vector<Channel *> ChannelList;
Poller(EventLoop