muduo网络库源码解析 三

来源:互联网 发布:努比亚专业相机软件 编辑:程序博客网 时间:2024/05/21 22:51

这一节我们来解析Reactor最核心的事件分发机制——Channel和Poller。每个Channel对象只属于一个EventLoop,因此每个Channel对象都只属于一个IO线程,并且只负责一个文件描述符,但是并不拥有这个fd,也不会在析构的时候关闭这个fd。首先来看一下构造函数原型Channel(EventLoop *loop, int fd);很明显,需要说明所属EventLoop,以及负责的文件描述符fd

事件类型的定义:

const int Channel::kNoneEvent = 0;const int Channel::kReadEvent = POLLIN | POLLPRI;const int Channel::kWriteEvent = POLLOUT;

事件处理函数:

void Channel::handleEvent(){  eventHandling_ = true;  if (revents_ & POLLNVAL) {    LOG_WARN << "Channel::handle_event() POLLNVAL";  }  if ((revents_ & POLLHUP) && !(revents_ & POLLIN)) {    LOG_WARN << "Channel::handle_event() POLLHUP";    if (closeCallback_) closeCallback_();  }  if (revents_ & (POLLERR | POLLNVAL)) {    if (errorCallback_) errorCallback_();  }  if (revents_ & (POLLIN | POLLPRI | POLLRDHUP)) {    if (readCallback_) readCallback_();  }  if (revents_ & POLLOUT) {    if (writeCallback_) writeCallback_();  }  eventHandling_ = false;}
update和disableAll用来注册和注销,其中update会调用EventLoop的updateChannel函数,disableAll 会将events设置为kNoneEvent.

Poller是对IO multiplexing的封装,在muduo中是个抽象基类,因为同时支持poll和epoll两种IO复用方式,和Channel类似,只属于一个EventLoop,只供其owner EventLoop在IO线程调用,所以无需加锁。我们先来看两个成员变量的类型:

typedef std::vector<pollfd> PollfdList;typedef std::map<int, Channel*> ChannelMap;PollfdList pollfds_;ChannelMap channels_;
PollfdList是一个vector,保存着pollfd,ChannelMap是一个map,保存着Channel*。key为fd,value为Channel*。Channel的index为在pollfds_中的下标。

updateChannel用来注册和修改channel,removeChannel用来注销channel。






原创粉丝点击