xd96dx Docs
  • c/c++
    • 网络编程
      • linux 网络
        • linux 网络io模型
        • Signal-Driven I/O Model(信号驱动)
        • Asynchronous I/O Model(异步IO)
      • IO多路复用
        • select 示例
        • poll 示例
        • epoll 示例
      • Reactor实例之 muduo 源码分析
    • stl实现
      • 容器(Containers)
        • Vector(动态数组)
        • List(双向链表)
        • Deque(二级动态数组)
  • 游戏开发
    • skynet 从demo到源码
      • server-client demo
      • skynet 源码分析-启动流程之初始化
      • skynet 源码分析-启动流程之创建service
      • skynet 源码分析-启动流程之线程池启动
Powered by GitBook
On this page
  • Reactor主要组件
  • 主要流程
  1. c/c++
  2. 网络编程

Reactor实例之 muduo 源码分析

Reactor 模型的实践库, 源码不难, 也很好分析, 和 beegfs 网络部分代码很像, 不过都大同小异

Previousepoll 示例Nextstl实现

Last updated 3 months ago

Reactor主要组件

EventLoop:

eventLoop 封装了Poller 和 Channel, 是muduo的事件循环, 负责事件处理, 任务分发, 定时器等功能

  • looping 表示事件循环是否正在运行, 在loop 时会设置为true, 退出后设为false

  • quit_ : 事件循环是否退出

  • eventHandling: 表示是否正在处理事件

  • callingPendingFunctors: 表示是否正在执行线程安全的任务队列

  • iteration: 事件循环次数

  • threadId_: eventLoop 的线程id

  • pollReturnTime_: poller 返回的时间戳

  • poller: 在linux下, 就是epoll, 用来监听channel 注册的事件

  • timerQueue: 定时管理器, 触发定时任务

  • weakupChannel_ 是用来监听 weakupFd_ 的, 他们和 pendingFunctors 是关联的, 在跨线程提交任务后, weakupChannel_ 会被 weakUp() 唤醒, 将任务放入 pendingFunctors 里, 在loop 中执行, 并清除weakupFd_ 的可读状态, 作用就是可以周期性的执行一部分其他线程提交的任务, 并恢复原状态

  • activeChannels: Poller里活跃的事件列表

  • currentActiveChannel_: 当前正在处理的channel

  • mutex_: 用来保护 pendingFunctors_ (主要是push_back, swap)

这是eventLoop 的 loop 方法, 监听poller 的事件, 然后执行, dopendingFunctors 里执行其他线程提交的任务, 不断循环

Channel

channel 主要用于封装fd 和 事件处理的回调, 负责具体事件的监听和处理

  • loop_ : 关联一个eventLoop 对象, 并将其注册到poller(epoll), 监听文件描述符事件

  • fd_ : io 描述符

  • events_: channel 要监听的事件, 事件发生时, poller 通知eventLoop, 并执行回调

  • revents_ : 实际发生的事件, 用来和监听的事件对比, 是否要执行相应注册的回调函数

  • index_ : poller中的索引

  • logHup_ : 是否记录挂起事件

  • tie_ : channel 与其他对象共享生命周期时, 用来绑定channel, muduo里使用的有 tcpConnection 和 curl

  • tied_ : 是否已经绑定对象

  • eventHandling: eventLoop 是否正在处理channel 的事件

  • addedToLoop_ : channel 是否已经添加到eventLoop中

  • readCallback_, writeCallback_, closeCallback_, errorCallback_ : 对应事件注册的回调函数

Poller

  • channels: 存储所有注册到poller的channel

  • ownerLoop_: 指向channel或poller的eventLoop

Poller 作为基类, 封装io多路复用, 在linux 下为epoll

  • epollfd_: epoll 文件描述符

  • events: 存储epoll_wait() 返回的事件

epoll主要流程

主要流程

EventLoop 作为muduo的事件循环, 在TcpServer.h 中, 主要给Acceptor 来建立新连接, 是整个tcpServer的起点, Acceptor 来监听事件, 并分发给其他工作线程

acceptor 在初始化时, 绑定 sever 的eventLoop, 并设置新连接进入的回调

start时, acceptor 开启监听并接受新连接, 线程池开始运作

在新连接进入时, 从线程池拿一个eventLoop, 并绑定 TcpConnection, 监听其事件

建立新的tcpConnection, 并绑定读写关闭错误事件

如read事件, 从channel 拿出fd, 并读取fd的内容, 即完成一次都事件, 其他事件类似相同

loop
channel
事件封装
回调函数
事件处理
poller
epoller
accptor init
threaPool start
newConnection
tcpConnection
read事件