当前位置: 首页 > news >正文

C/C++ Select Poll Epoll 多路转接

多路转接:

  • 并发性​​:单线程/进程即可同时处理多个I/O操作,无需创建大量线程或进程
  • ​非阻塞​​:在监听过程中,程序不会阻塞,仅在检测到就绪事件时才触发处理
  • ​事件驱动​​:基于文件描述符的就绪状态(如可读、可写、异常)执行回调或轮询操作

    用个通俗易懂的例子举例:一个人钓鱼,掌管着多个鱼竿,哪个鱼竿的浮漂动,才会去拉起钓竿。

多路转接----select与poll与epoll

一.select

1.参数

select可以同时管理和监听多个文件描述符,程序会停在select函数,直到有就绪事件。

nfds----鉴定文件描述符中最大值+1  如 1 4 7三个描述符 nfds应为8

readfds/writefds/exceptfds----确定关心哪些文件描述符的哪些事件--读 写 异常

timeval----

1.  NULL--阻塞等待

​​适用场景​​:需持续监控I/O事件,无超时需求。

2.   ​​0-非阻塞等待
select立即返回,仅检查当前描述符状态(轮询模式)

​​适用场景​​:高频检测I/O状态,避免程序阻塞。

3. 指定数字 ​​超时模式​​(timeout > 0
在指定时间内等待事件就绪,超时后返回0。例如,设置超时为3秒:

fd_set可以认为是一个bit位图,通过在第几个bit位置确定是哪个文件描述,因此他的大小是有限制的,取决于fd_set,这与内核系统的设置有关。

如readfds 0001101 //就是关心 0,2,3文件描述符的读事件。

然后假如说0文件描述符的读事件就绪,那么select就会返回

原来的0001101会被修改为0000001,其他没就绪的就被置空。

但是对位操作比较麻烦,所以为我们提供了接口。

2.返回值

1.执行成功则返回文件描述词状态已改变的个数

2. 如果返回0代表在描述词状态改变前已超过timeout时间。 

3.当有错误发生时则返回-1,错误原因存于errno,此时参数readfds,writefds, exceptfds 和 timeout 的值变成不可预测。

3.总结

缺点:

1.需要自己手动管理文件描述符,在循环监听时,每次都需要手动设置fd集合。

2.每次使用fd集合都需要将其从用户态拷贝到内核态

3.select每次监听,都需要在内核态进行遍历所有fd

4.select能监听的fd有限。

二.Poll

poll与select比较相似。

1.参数

fds---

就相当于将select的readfds/writefds 整合起来。

一个pollfd 中包含了,需要监听文件描述符,与需要监听的事件,和返回就绪事件。

nfds---fds数组的数量

2.返回值

3.总结

缺点:

1.每次内核需要轮询检测哪些事件就绪

2.每次使用fd集合都需要将其从用户态拷贝到内核态

3.随着监听fd的增多,每次可能只有几个fd就绪,效率会随着下降。

优点:

1.不需要在循环设置监听事件,接口使用更方便

2.没有监听事件数量设置(但过多,性能也下降)

三.epoll

1.函数与参数

int epoll_create(int size);

返回一个epoll句柄,size可填可不填,记住如果不需要epoll模型,要close()关闭

作用:在内核创建一个epoll模型

何为epoll模型

简单的概括来说

一个epoll模型中有一个红黑树和一个链表

红黑树有将fd和event封装起来的结点epollitem,每次插入删除通过红黑树进行,所以效率非常的高,其次当事件就绪,与其对应的驱动程序会调用epollitem相应的回调函数,将其加入链表中,

那么链表就可以存储就绪事件

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

epfd句柄

op操作符

fd需要监听的文件描述符

event这里我们只需要关心events和data.fd与fd设置一样即可 即可

events:

ET模式:文件描述符状态变化​

例如读事件从有无数据到有数据   类似电平0到1跳转的那一瞬间才会触发

例如写事件缓冲区空间从无到有 类似电平从1到0跳转的那一瞬间

所以我们必须要一次性将数据读完,

所以应文件描述符设置非阻塞模式,这是因为read阻塞式读取一次可能不会将数据读完,所以我们应采用非阻塞轮询的方式,直到所有数据读完。

LT模式:持续通知

例如只要有数据,就一直在就读队列, 类似电平只要为1就为真。

epoll默认为LT模式。

若是我们想设置ET模式

只需要 事件 | 模式即可

ev.events = EPOLLIN | EPOLLET;

int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);

epfd句柄

events传入要监听的events,epoll会将就绪事件赋值到events数据中

maxevnets是events结构体数组的元素个数

timeout与上述epoll相似 

返回值与poll一样

2.优点

1.使用方便,不需要每次再循环设置监听事件,实现输入输出参数分离

2.数据拷贝轻量,只需要add时候加入文件标识符的时候需要拷贝(而其他两个每次循环都要进行拷贝)

3.事件回调机制,当一个事件就绪,不需要循环遍历,只需要调用回调函数,将当前结点直接加入就绪队列。

4.没有文件限制

http://www.xdnf.cn/news/556993.html

相关文章:

  • python -> matplotlib简单用法
  • Unity3D仿星露谷物语开发47之砍树时落叶特效
  • Wan2.1 加速推理方法
  • 使用cursor自动生成前后端分离的web应用程序
  • ROS2 pkg 创建功能包
  • [ 计算机网络 ] 深入理解OSI七层模型
  • 经验过程简介与suprema的集中(Guntuboyina理论统计学笔记)
  • QT高DPI支持
  • linux之 pcie MSI-X中断编程
  • 自动化测试核心知识梳理与 Java 代码详解
  • 基于正点原子阿波罗F429开发板的LWIP应用(3)——Netbiosns功能
  • 嵌入式培训之系统编程(一)标准IO、文件操作
  • Liquid Wire 柔性应变传感器:金属凝胶导体 | 仿生肌肉长度监测 | 高精度动作控制
  • 特定领域 RAG中细调嵌入模型能否提升效果?
  • IVX:重构 AI 原生开发范式,让模型调用成为指尖艺术​
  • PostgreSQL简单使用
  • 深入浅出人工智能:机器学习、深度学习、强化学习原理详解与对比!
  • 【深度学习-Day 14】从零搭建你的第一个神经网络:多层感知器(MLP)详解
  • 第六天的尝试
  • 服务器部署1Panel
  • 證券行業證券交易系統開發方案
  • 基于SpringBoot+Vue的学籍管理系统的设计与实现
  • Kubernetes在线练习平台深度对比:KillerCoda与Play with Kubernetes
  • 【开源工具】文件夹结构映射工具 | PyQt5实现多模式目录复制详解
  • 【鸿蒙开发】Hi3861学习笔记- MQTT通信
  • 统一端点管理(UEM):定义、优势与重要性
  • 从零开始:Python 从0到1轻松入门
  • 易路 AI 招聘:RPA+AI 颠覆传统插件模式,全流程自动化实现效率跃迁
  • 物业收费智能化:如何实现账单零差错自动生成?
  • SpringBean模块(三)具有生命周期管理能力的类(1)AutowireCapableBeanFactory