muduo学习笔记(一)

muduo学习笔记(一)
这两晚读了一下 muduo的代码,从最简单的EchoServer切入,结合 muduo作者的博客,理清类之间的关系,写了一下阅读心得。

主要从中学习几点:
1. 服务器端网络编程(结合Unix网络编程)
    非阻塞IO,IO多路复用,多线程。
2. boost库的常用用法(结合 Beyond the C++ Standard Library: An Introduction to Boost)
    应用层提供逻辑(Service)注册callback到通信层,使用boost::bind和boost::function。
3. 基于C++的程序设计 (C++ coding standard: 101)
    设计风格,编程风格,编程规范

对代码的理解:

EchoServer:
    提供事件处理逻辑,供TcpServer回调,如连接建立、断开,消息收发等

TcpServer:
    1. 接受连接、断开连接
        管理TcpConnection:创建、持有、删除TcpConnection
    2. 收发数据
        委托TcpConnection
    3. 使1、2持续不断的进行
        委托EventLoop。接受新连接时,创建TcpConnection对象,从线程池中取出线程并处理。
    4. 使1、2能并发的执行
        ThreadPool
    5. 连接建立、断开,数据接收后,能交由应用层处理
        应用层提供处理逻辑,并注册callback

EventLoop:
    1. 使Server持续运转;与TcpConnection交互
    2. 使用poll/epoll等IO多路复用等待事件发生
    3. 为使线程阻塞在poll/epoll上时,能及时唤醒,引入了eventfd。向eventfd写入数据,能使poll/epoll很快返回。
    4. 为保证线程安全,在EventLoop::loop()里的操作,必须都在EventLoop所在的线程中执行,因此需要操作投递,即runInLoop/queueInLoop两个函数的功能。
    5. 同时提供了定时操作,用timerfd实现。
    6. Server主线程的EventLoop: 负责newConnection/removeConnection,即listen & accept
       IO线程的EventLoop:负责read/write。如果没有IO线程,则由主线程负责IO。

EventLoopThreadPool:
    1. 管理IO线程: std::vector<EventLoopThread*>, std::vector<EventLoop*>
    2. 新连接来后,从线程池中取出线程接受连接,进行后续通信。

EventLoopThread:
    初始化本线程内的EventLoop,并开始循环。

TcpConnection:
    1. send/recv data
    2. fd由Channel维持,因此 TcpConnection读写数据都通过Channel进行,从Channel中读出,往Channel中写。
    3. 在一次send中,如果数据没有全部发送完,剩余的数据将保存在Buffer中,留待下一次发送。下一次发送通过Channel进行:调用Channel的enableWriting, 更新Channel属性(加上write event),并向Poller注册。当IO ready后,EventLoop将处理该次写事件,即Channel::handleEvent.
     流程如下:
      STEP A:
        1. TcpConnection::send() -> sendInLoop()
        2. Data remaining?
            Yes:append data to outputBuffer_;
                Channel::enableWriting() -> add write event && update() -> EventLoop::updateChannel() -> Poller::updateChannel():modify fd's events
            No: Channel::disableWriting()
      STEP B:
        1. Channel::handleEvent() -> writeCallback_, i.e. TcpConnection::handleWrite()
        2. Data remaining? Goto A.2

Channel:
    通道,fd的对象化?
    在网络程序中,涉及各种对象需要与IO交互,如Timer,Connection,Acceptor, Connector。在Linux中,与系统打交道的是文件描述符,fd。Timer等这些对象通过操作fd进行IO,IO多路复用需要管理这些fd。Channel则相当于对fd的代理,方便对fd进行各种操作,如注册、响应事件。Poller维持fd与Channel的映射,对通道进行操作,就会反映到相应的fd上;而fd状态有变化,则会使相应的Channel变成Active状态,促发事件响应、进行实际IO操作。


你可能感兴趣的:(muduo学习笔记(一))