Muduo库代码剖析(1)

理论知识

阻塞, 非阻塞, 同步, 异步

数据准备 - 网络IO阶段1

  • 阻塞 : 当前线程调用IO方法的线程进入阻塞状态
  • 非阻塞 : 不会改变线程状态, 通过返回值判断
    • size == 0 对端关闭了连接
    • size > 0 接收到资源
    • size == 0 && errno = EAGAIN

数据读写 - 网络IO阶段2

  • 并发同步 : 同步IO接口 - 应用程序自己把数据从接收缓冲区搬过来 select / poll / epoll
  • 并发异步 : 异步IO接口 - 应用程序发出请求, 传入sockfd, buf和sigio信号(通知方式), 由系统把数据搬到buf中, 当系统搬完后, 对应用程序发送sigio通知, 告诉应用程序有数据发来且已经搬运完成.

在处理IO时, 阻塞和非阻塞都是同步IO, 只有使用了特殊的的API才是异步.


Linux上的五种IO模型

  • 阻塞 : 同步阻塞
  • 非阻塞 : 同步非阻塞
  • IO复用 : select / poll / epoll 监听fd是否可读, 返回可读fd.
  • 信号驱动 : 注册SIGIO信号, 发起请求, 拷贝过程还是自己承担
  • 异步 : 同上

一个好的网络服务器

  • 非阻塞 + IO复用 : 就是用IO复用替代轮询操作
  • epoll + 非阻塞IO + 线程池

Reactor模型

image-20250115173257202


IO复用

  • select : 会设置一个保存句柄的数组, 会轮循扫描数组, 拷贝句柄数据结构会有巨大开销
  • epoll :
    • 调用epoll_create()在内核申请一个文件系统的数据结构, 结构包括红黑树(存储socketfd)和双向链表(存储发生事件的fd)
    • 调用epoll_ctl()像对象中(红黑树)添加要监视的所有socketfd
    • 调用epoll_wait()收集发生事件的fd资源

事件触发模式

  • LT模式(水平触发) : 只要内核数据没被读完, 处于可读可写的状态, 就会一直上报数据(默认)
  • ET模式(边缘触发) : 仅在状态变化时(不可读->可读)进行通知
  • Muduo库采用的LT模式
    • 不会丢失数据或消息
    • 低延迟处理, ET会针对一个事件一直读取, 有可能分配不均, LT就非常公平, 延迟较低.
    • 便于跨平台使用

Muduo库代码剖析(1)
http://example.com/2025/04/07/Moduo库代码剖析(1)/
作者
天目中云
发布于
2025年4月7日
许可协议