Kanon(五): PollerBase(IO解多路复用器)

PollerBaseReactor中充当IO解多路复用器(I/O Demultiplexer)

Q:为什么是IO解多路复用器,用到的API常称为IO多路复用吗?
A: 所谓IO多路复用是复用监视fd集合,有多个源(source),当其中有事件触发,对应的fd转变为活跃状态,就会形成对应的活跃fd集合(Output),我们得到的就是活跃fd的集合(具体获取方式各API有别),然后分发,这就是IO解多路复用。

相信读者知道:
select()/poll()/epoll_wait()本质都是同步API,而阻塞与非阻塞取决于timeout实参,如果指定为负数,就是阻塞的,其他的就是非阻塞,只不过有定时。该性质也可以用于实现定时器操作,不过精度是毫秒(ms),相比timerfd而言要更低。

kanon支持两种IO多路复用API(—表示抽象为):

  • poll()Poller
  • epoll_wait()Epoller
    均继承自PollerBase

PollerBase是一个抽象基类,并且没有任何数据成员,因此是接口类,即只有纯虚函数。

但派生类的实现却是截然不同的,这是因为poll()需要我们维护连续的struct pollfd[],而epoll并不需要,同时我们也需要一个加速查找的缓存,比如哈希表或红黑树,这里我采用的是哈希表。实际上,和epoll在内核维护事件表(红黑树)和就绪列表(链表)类似。
除此之外,Epoller可以支持水平触发(Level trigger)边缘触发(Edge trigger),这点也是和Poller很大的不同。epoll_wait()返回的就绪列表需要用struct epoll_event[]去接受,故作为数据成员。

用类图来表示如下:
poller.drawio.png