muduo - 概要简述

    • 以下内容,主要援引于自述

设计目标

  • 线程安全,支持多线程

  • 只支持 Linux,不支持 Windows

  • IO multiplexing 使用 poll 和 epoll

  • 主要支持 x86-64,兼顾 IA32

  • 不支持 UDP,只支持 TCP

  • 不支持 IPv6,只支持 IPv4

  • 不考虑广域网应用,只考虑局域网

  • 只支持一种使用模式:non-blocking IO + one event loop per thread,不考虑阻塞 IO

  • API 简单易用,只暴露具体类和标准库里的类,不使用 non-trivial templates,也不使用虚函数

  • 只做 library,不做成 framework

  • 争取全部代码在 5000 行以内(不含测试)

  • 搭配 Google Protocol Buffers RPC

实现简述

Muduo是基于Reactor模式的网络库,其核心是个事件循环EventLoop,用于响应计时器和IO事件。Muduo采用基于对象(object based)而非面向对象(object oriented)的设计风格,其接口多以boost::function + boost::bind表达。

头文件关系

  • 白底:public
  • 黑底:private

接口细节

公开接口

  • Buffer仿 Netty ChannelBuffer 的 buffer class,数据的读写通过 buffer 进行

  • InetAddress封装 IPv4 地址 (end point),注意,muduo 目前不能解析域名,只认 IP

  • EventLoop反应器 Reactor,用户可以注册计时器回调

  • EventLoopThread启动一个线程,在其中运行 EventLoop::loop()

  • TcpConnection整个网络库的核心,封装TCP连接

  • TcpClient用于编写网络客户端,能发起连接,并且有重试功能

  • TcpServer用于编写网络服务器,接受客户的连接

  • 在这些类中,TcpConnection的生命期依靠 shared_ptr 控制(即用户和库共同控制)。Buffer的生命期由TcpConnection控制。其余类的生命期由用户控制。

  • HttpServer 和 Inspector,暴露出一个 http 界面,用于监控进程的状态,类似于 Java JMX。这么做的原因是,《程序员修炼之道》第 6 章第 34 条提到“对于更大、更复杂的服务器代码,提供其操作的内部试图的一种漂亮技术是使用内建的 Web 服务器”,Jeff Dean 也说“(每个 Google 的服务器进程)Export HTML-based status pages for easy diagnosis”。

内部实现

  • Channel是 Selectable IO channel,负责注册与响应 IO 事件,它不拥有 file descriptor。它是 Acceptor、Connector、EventLoop、TimerQueue、TcpConnection 的成员,生命期由后者控制。

  • Socket封装一个 file descriptor,并在析构时关闭 fd。它是 Acceptor、TcpConnection 的成员,生命期由后者控制。EventLoop、TimerQueue 也拥有 fd,但是不封装为 Socket。

  • SocketsOps 封装各种 sockets 系统调用。

  • EventLoop封装事件循环,也是事件分派的中心。它用 eventfd(2) 来异步唤醒,这有别于传统的用一对 pipe(2) 的办法。它用 TimerQueue 作为计时器管理,用 Poller 作为 IO Multiplexing。

  • Poller是 PollPoller 和 EPollPoller 的基类,采用“电平触发”的语意。它是 EventLoop 的成员,生命期由后者控制。

  • PollPollerEPollPoller封装 poll(2) 和 epoll(4) 两种 IO Multiplexing 后端。Poll 的存在价值是便于调试,因为 poll(2) 调用是上下文无关的,用 strace 很容易知道库的行为是否正确。

  • Connector用于发起 TCP 连接,它是 TcpClient 的成员,生命期由后者控制。

  • Acceptor用于接受 TCP 连接,它是 TcpServer 的成员,生命期由后者控制。

  • TimerQueuetimerfd实现定时,这有别于传统的设置 poll/epoll_wait 的等待时长的办法。为了简单起见,目前用链表来管理 Timer,如果有必要可改为优先队列,这样复杂度可从 O(n) 降为 O(ln n) (某些操作甚至是 O(1))。它是EventLoop的成员,生命期由后者控制。

  • EventLoopThreadPool用于创建IO线程池,也就是说把 TcpConnection 分派到一组运行 EventLoop 的线程上。它是 TcpServer 的成员,生命期由后者控制。

线程模型

Muduo的线程模型符合one loop per thread + thread pool模型。

  • 每个线程最多有一个 EventLoop

  • 每个TcpConnection必须归某个EventLoop管理:所有IO操作,所有FDFile Descriptor读写

    • TcpConnection所在的线程由其所属的EventLoop决定

    • TcpConnectionEventLoop是线程安全的,可以跨线程调用

  • TcpServer直接支持多线程,它有两种模式:

    • 单线程,AcceptorTcpConnection用同一个线程做IO。

    • 多线程,AcceptorEventLoop在同一个线程,另外创建一个EventLoopThreadPool,新到的连接会按Round-Robin方式分配到线程池中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值