网络: 多路复用

  • 概念: 多路复用: 一种通信传输技术, 使多条数据流或信号共享同一传输介质
  • 网络中的多路复用: 一个进程能够同时监控多个文件描述符的IO事件

特点

select

缺点

  • 设置关注文件描述符的结构是位图, 有数量限制
  • fdset无法复用, 每次都要初始化
  • 用户态和内核态之间的拷贝较多
  • 检查关注的fd, 已就绪的fd都需要遍历

poll

优点

  • 采用结构体, 解决select文件描述符的个数限制

缺点

  • 用户态和内核态之间的拷贝较多
  • 检查关注的fd, 已就绪的fd仍需要遍历

epoll

优点

  • 检查就绪的文件描述符更快(为O(1), 就绪队列结构)
  • 不用频繁的在用户态和内核态之间拷贝(红黑树 + 双链表, 会记录要关注的fd和就绪的fd). 相比于select不用老是传递之前的文件描述符

缺点

  • 内核要维护红黑树 + 双链表(更占内存)
  • 当要监听的文件描述符较少时, 其速度不一定比poll快

epoll触发机制

  • LT(水平触发): 只要底层有事件就绪且没被取走, 就会一直通知上层
  • ET(边缘触发): 只有就绪事件变化的时候, 才会通知上层(且只通知一次)

原理

select

  • 将关注的所有fd, 一次性从用户态拷贝到内核态
  • 在内核态中遍历每个fd, 检测是否有数据到达
  • 将所有fd状态从, 从内核态拷贝回用户态, 并返回就绪fd个数
  • 用户态遍历所有fd, 找到已就绪的fd, 然后进行事件处理

poll

  • 和select类似(只是用一个结构体封装了一下)

epoll

  • 和select,poll类似, 不过在内核维护了红黑树 + 双链表且使用回调机制减少了select的缺点

操作

  • select

头文件: <sys/select.h>

int select (int nfds, fd_set *readfds , fd_set *writefds , fd_set *exceptfds , struct timeval *timeout)

复制代码
nfds   : 需要监视的最大的文件描述符值+1. (用来确定遍历范围)
read   : 可读文件描述符的集合
write  : 可写文件描述符的集合
except : 异常文件描述符的集合
timeout: 超时时间(若超过该时间, 还没有事件就绪就返回) 
         NULL: 一直阻塞
         0: 不阻塞

fd_set系列

复制代码
void FD_ZERO(fd_set *set);              // 用来清除描述词组set的全部位
void FD_CLR(int fd, fd_set *set);       // 用来清除描述词组set中相关fd的位
void FD_SET(int fd, fd_set *set);       // 用来设置描述词组set中相关fd的位
int  FD_ISSET(int fd, fd_set *set);      // 用来测试描述词组set中相关fd的位是否为真
  • poll

头文件: <poll.h>

int poll(struct pollfd *fds , nfds_t nfds , int timeout);

复制代码
struct pollfd {
    int fd;         //文件描述符
    short events;   //监听事件集合
    short revents;  //返回事件集合
};

nfds: fds数组的长度
timeout: 超时时间

events与revents的取值

  • epoll

epoll_create

复制代码
函数  : int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
功能  : 创建一个epoll模型
返回值: 用一个数表示这个epoll
参数  : size: 文件描述符个数
注    : 但自从linux2.6.8之后,size参数是被忽略的
        用完之后, 必须调用close()关闭

epoll_ctl

复制代码
函数:int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
功能:注册要监听的事件类型

epfd : epoll_create()的返回值(epoll的句柄)
fd   : 需要监听的fd
event: 告诉内核需要监听什么事
op   : 用三个宏来表示
       EPOLL_CTL_ADD :注册新的fd到epfd中;
       EPOLL_CTL_MOD :修改已经注册的fd的监听事件;
       EPOLL_CTL_DEL :从epfd中删除一个fd;

epoll_wait

复制代码
int epoll_wait(int epfd,struct epoll_event * events,int maxevents, nt timeout);
功能: 收集在epoll监控的事件中已经发送的事件

events   :分配好的epoll_event结构体数组.
maxevents: 告诉内核这个events有多大,这个 maxevents的值不能大于创建epoll_create()时的size.
timeout  : 超时时间(0会立即返回,-1是永久阻塞)

返回值:
      成功 :返回对应I/O上已准备好的文件描述符数目
      0    :表示已超时
      小于0:表示函数失败


epoll将会把发生的事件赋值到events数组中 
events不可以是空指针,内核只负责把数据复制到这个events数组中,不会去帮助我们在用户态中分配内存
相关推荐
白帽小阳22 分钟前
我的AI辅助开发工具链2026版:从编码到部署的全栈智能实践
网络·人工智能·学习·安全·自动化
衣舞晨风41 分钟前
什么样的 AI 网关算是一个好网关
网络·人工智能·网关·ai·大模型·ai网关
Keepingrun1 小时前
http登录和授权
网络·网络协议·http
Sirius Wu1 小时前
OpenClaw 并发安全完整详解
网络·人工智能·安全·ai·架构·aigc
rcms152702692182 小时前
AMAT 0190-27952-04 终端服务器
网络
海外数字观察家2 小时前
品未云:博兹瓦纳华商批发零售一体化 ERP,破解本土软件适配难题|CSDN 技术分享
大数据·网络·人工智能·博兹瓦纳进销存系统·博兹瓦纳收银系统·博兹瓦纳erp系统·博兹瓦纳仓库管理系统
段一凡-华北理工大学3 小时前
AI Agent 从入门到封神:24 讲打造你的超级智能体~系列文章23:从Demo到上线:Agent应用的架构设计、性能优化与成本控制实战
运维·网络·人工智能·性能优化·高炉炼铁·工业智能体
leagsoft_10033 小时前
从“策略看不清”到“风险可收敛”:某高端精密制造企业的网络安全策略治理实践
网络·web安全·制造
paopaokaka_luck3 小时前
基于Springboot3+Vue3的宠物殡葬管理系统(webSocket实时通讯、接入腾讯地图、支付宝沙盒支付、Echarts图形化分析)
java·开发语言·网络·后端
承渊政道3 小时前
【从零开始大模型开发与微调:基于PyTorch与ChatGLM】(从退化问题到信息高速公路:ResNet残差网络实战拆解)
网络·人工智能·pytorch·深度学习·resnet·chatglm·卷积