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模型
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)/