muduo网络库源码解析 三

26 篇文章 1 订阅

这一节我们来解析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。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值