【Linux】I/O多路复用模型 select、poll、epoll

2024-06-21 03:44

本文主要是介绍【Linux】I/O多路复用模型 select、poll、epoll,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

创作不易,本篇文章如果帮助到了你,还请点赞 关注支持一下♡>𖥦<)!!
主页专栏有更多知识,如有疑问欢迎大家指正讨论,共同进步!
🔥Linux系列专栏:Linux基础 🔥

给大家跳段街舞感谢支持!ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ

在这里插入图片描述


目录

    • 多路:
    • 复用:
  • 一、select 模型
  • 二、poll 模型
  • 三、epoll 模型
    • 水平触发模式 EPOLLLT
    • 边缘触发模式 EPOLLET
    • 示例

在监听 socket 时,需要分配多个线程/进程维护多个 socket 连接,I/O 多路复用技术就是用来使用一个进程来监听维护多个 socket 连接

多路:

I/O 状态:可读、可写

复用:

使用一个线程/进程监听处理 I/O 事件,复用多个 socket 请求


一、select 模型

select 原理:

  • 1.创建一个文件描述符集合 fd_set set 0 不监听 1 监听

  • 2.设置文件描述符的状态

    • FD_ZERO(&set); 初始化监听集合,将位码初始化为 0
    • FD_SET(int sockfd,&set); 将 sockfd 在集合中对应的位设置成 1
    • FD_CLR(int sockfd,&set); 将 sockfd 在集合中对应的位设置成 0
    • int code = FD_ISSET(int sockfd,&set); 返回 sockfd 在文件描述符集合中的位码
  • 3.调用 select 函数,传入文件描述符集合 set


select 函数:

#include <sys/select.h>
#include <unistd.h>int ready = select(int nfds,fd_set* readfds,fd_set* writefds,fd_set* errorfds,struct timeval* timeout);

参数:

  • nfds: 需要监视的最大文件描述符值加 1
  • readfds:监听读事件,设为 NULL 不监听
  • writefds:监听写事件,设为 NULL 不监听
  • errorfds:异常事件
  • timeout:阻塞时间,设为 NULL 为阻塞监听,定义 timeval 结构体将成员设置为 0 为非阻塞。定时阻塞支持微妙级别定时

返回值:返回就绪的 socket 数量

select 函数会将整个文件描述符集合 set 拷贝到内核中,让内核检查是否有读/写事件,内核遍历文件描述符集合,
如果有事件发生,内核将对应的 socket 标记位可读/可写,然后将整个文件描述符集合 set 拷贝回用户空间,用户再遍历文件描述符集合找到就绪的 socket 进行后续处理


select 的缺点:

  • 1.Linux 平台受最大文件描述符数量限制,select 的最大监听数为 1024
  • 2.select 监听就绪后只返回就绪的数量,需要用户遍历找到就绪的 socket
  • 3.监听集合会在监听到就绪后被修改,需要用户自行分离传入传出设置
  • 4.轮询监听,轮询数量大, CPU 处理性能下降
  • 5.拷贝和挂载开销大
  • 6.设置监听不灵活,无法对不同的 socket 设置不同的监听类型

二、poll 模型

poll 监听事件种类更丰富,对监听和就绪数组进行了传入传出分离

poll 不受最大文件描述符数量限制,支持用户自定义长度结构体数组作为集合

#include <poll.h>int ready = poll(struct pollfd* fds, int nfds, int timeout);

参数:

  • fds:监听数组
    • struct pollfd listen_array[4096]; //监听数组
    • listen_array[0].fd = sockfd; //监听 sockfd,-1 取消监听
    • listen_array[0].events = POLLIN|POLLOUT|POLLERR; //设置监听事件
    • listen_array[0].revents; //如果监听的 socket 就绪,系统将就绪事件传到 revents 中
  • nfds:监听数组大小
  • timeout:阻塞时间,-1 为阻塞监听,0 为非阻塞。>0 定时阻塞 只支持毫妙级定时

poll 的缺点

  • 1.轮询监听,轮询数量大, CPU 处理性能下降
  • 2.拷贝和挂载开销大
  • 3.只有特定的 Linux 版本才能使用

三、epoll 模型

结合了 select 和 poll 的优势

创建监听树(创建于内核中,使用红黑树):

#include <sys/epoll.h>
int epfd = epoll_create(int size);

参数:size 为监听数量。返回值:指向监听树的描述符。


监听树节点

struct epolevent node;
node.data.fd = sockfd;
node.events = EPOLLIN|EPOLLOUT|EPOLLERR;

epoll 监听到就绪直接返回就绪节点,用户遍历处理这些就绪 socket 即可


向监听树中添加节点:

epoll_ctl(int epfd,EPOLL_CTL_ADD,int sockfd,struct epollevent* node);

在监听树中删除节点:

epoll_ctl(int epfd,EPOLL_CTL_DEL,int sockfd,NULL);

修改监听树中的节点(修改监听的事件):

epoll_ctl(int epfd,EPOLL_CTL_MOD,int sockfd,&node);

监听事件发生:

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

参数:

  • epfd:监听树
  • events:监听事件数组
  • maxevents:最大就绪数大小
  • timeout:阻塞时间,-1 为阻塞监听,0 为非阻塞。>0 定时阻塞

epoll 的优点:

  • 没有监听数量限制,不用担心轮询问题
  • epoll 使用了事件驱动的方式,监听集合在内核层,避免了每次调用时的重复设置和遍历操作。内核会将就绪的文件描述符直接返回
  • 监听事件种类更丰富,可以对不同的 socket 设置不同的事件监听,对监听和就绪数组进行了传入传出分离


水平触发模式 EPOLLLT

  • 当可读或可写事件发生时,epoll 会持续通知用户处理直到用户处理。
  • 以在任何时候处理这些通知,不必立即响应
  • 水平触发适用于处理数据量较大或需要缓冲数据的情况,因为可以确保用户不会错过任何数据

多个事件同时发生可能导致重复处理,可以使用 EPOLLONESHOT设置为只触发一次通知


边缘触发模式 EPOLLET

  • 当可读或可写事件发生时,epoll 会立即通知(只会通知 1 次)
  • 应用程序需要在收到通知后立即处理相应的 I/O 事件,否则可能会丢失事件
  • 边缘触发适用于处理大量并发连接且数据量较小的情况,可以减少不必要的系统调用和上下文切换。

边缘触发模式一般和非阻塞 I/O 搭配使用,直到系统调用(如 read 和 write)返回错误,错误类型为 EAGAIN 或 EWOULDBLOCK


示例

    //创建监听树并将serversock设置监听读事件if((epfd = epoll_create(EPOLL_MAX)) == -1){perror("epoll_initializer: create epoll tree failed");}struct epoll_event node;node.data.fd = sockfd;node.events = EPOLLIN;//添加节点epoll_ctl(epfd,EPOLL_CTL_ADD,sockfd,&node);int readycode;struct epoll_event readyarray[EPOLL_MAX];int i = 0;int flag = 1;while(flag){if((readycode = epoll_wait(epfd,readyarray,EPOLL_MAX,-1)) == -1){perror("epoll_wait failed");}else{i = 0;//根据readycode就绪数量处理就绪while(readycode){//判断就绪if (readyarray[i].data.fd == server_sockfd){//server sock ready//添加tcp连接任务}else{//client sock ready//添加响应处理任务}--(readycode);++i;}}}

在这里插入图片描述

大家的点赞、收藏、关注将是我更新的最大动力! 欢迎留言或私信建议或问题。
大家的支持和反馈对我来说意义重大,我会继续不断努力提供有价值的内容!如果本文哪里有错误的地方还请大家多多指出(●'◡'●)

这篇关于【Linux】I/O多路复用模型 select、poll、epoll的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1080118

相关文章

linux生产者,消费者问题

pthread_cond_wait() :用于阻塞当前线程,等待别的线程使用pthread_cond_signal()或pthread_cond_broadcast来唤醒它。 pthread_cond_wait() 必须与pthread_mutex 配套使用。pthread_cond_wait()函数一进入wait状态就会自动release mutex。当其他线程通过pthread

Linux 安装、配置Tomcat 的HTTPS

Linux 安装 、配置Tomcat的HTTPS 安装Tomcat 这里选择的是 tomcat 10.X ,需要Java 11及更高版本 Binary Distributions ->Core->选择 tar.gz包 下载、上传到内网服务器 /opt 目录tar -xzf 解压将解压的根目录改名为 tomat-10 并移动到 /opt 下, 形成个人习惯的路径 /opt/tomcat-10

RedHat运维-Linux文本操作基础-AWK进阶

你不用整理,跟着敲一遍,有个印象,然后把它保存到本地,以后要用再去看,如果有了新东西,你自个再添加。这是我参考牛客上的shell编程专项题,只不过换成了问答的方式而已。不用背,就算是我自己亲自敲,我现在好多也记不住。 1. 输出nowcoder.txt文件第5行的内容 2. 输出nowcoder.txt文件第6行的内容 3. 输出nowcoder.txt文件第7行的内容 4. 输出nowcode

【Linux进阶】UNIX体系结构分解——操作系统,内核,shell

1.什么是操作系统? 从严格意义上说,可将操作系统定义为一种软件,它控制计算机硬件资源,提供程序运行环境。我们通常将这种软件称为内核(kerel),因为它相对较小,而且位于环境的核心。  从广义上说,操作系统包括了内核和一些其他软件,这些软件使得计算机能够发挥作用,并使计算机具有自己的特生。这里所说的其他软件包括系统实用程序(system utility)、应用程序、shell以及公用函数库等

一份LLM资源清单围观技术大佬的日常;手把手教你在美国搭建「百万卡」AI数据中心;为啥大模型做不好简单的数学计算? | ShowMeAI日报

👀日报&周刊合集 | 🎡ShowMeAI官网 | 🧡 点赞关注评论拜托啦! 1. 为啥大模型做不好简单的数学计算?从大模型高考数学成绩不及格说起 司南评测体系 OpenCompass 选取 7 个大模型 (6 个开源模型+ GPT-4o),组织参与了 2024 年高考「新课标I卷」的语文、数学、英语考试,然后由经验丰富的判卷老师评判得分。 结果如上图所

大语言模型(LLMs)能够进行推理和规划吗?

大语言模型(LLMs),基本上是经过强化训练的 n-gram 模型,它们在网络规模的语言语料库(实际上,可以说是我们文明的知识库)上进行了训练,展现出了一种超乎预期的语言行为,引发了我们的广泛关注。从训练和操作的角度来看,LLMs 可以被认为是一种巨大的、非真实的记忆库,相当于为我们所有人提供了一个外部的系统 1(见图 1)。然而,它们表面上的多功能性让许多研究者好奇,这些模型是否也能在通常需要系

Windows/macOS/Linux 安装 Redis 和 Redis Desktop Manager 可视化工具

本文所有安装都在macOS High Sierra 10.13.4进行,Windows安装相对容易些,Linux安装与macOS类似,文中会做区分讲解 1. Redis安装 1.下载Redis https://redis.io/download 把下载的源码更名为redis-4.0.9-source,我喜欢跟maven、Tomcat放在一起,就放到/Users/zhan/Documents

Linux系统稳定性的奥秘:探究其背后的机制与哲学

在计算机操作系统的世界里,Linux以其卓越的稳定性和可靠性著称,成为服务器、嵌入式系统乃至个人电脑用户的首选。那么,是什么造就了Linux如此之高的稳定性呢?本文将深入解析Linux系统稳定性的几个关键因素,揭示其背后的技术哲学与实践。 1. 开源协作的力量Linux是一个开源项目,意味着任何人都可以查看、修改和贡献其源代码。这种开放性吸引了全球成千上万的开发者参与到内核的维护与优化中,形成了

人工和AI大语言模型成本对比 ai语音模型

这里既有AI,又有生活大道理,无数渺小的思考填满了一生。 上一专题搭建了一套GMM-HMM系统,来识别连续0123456789的英文语音。 但若不是仅针对数字,而是所有普通词汇,可能达到十几万个词,解码过程将非常复杂,识别结果组合太多,识别结果不会理想。因此只有声学模型是完全不够的,需要引入语言模型来约束识别结果。让“今天天气很好”的概率高于“今天天汽很好”的概率,得到声学模型概率高,又符合表达

智能客服到个人助理,国内AI大模型如何改变我们的生活?

引言 随着人工智能(AI)技术的高速发展,AI大模型越来越多地出现在我们的日常生活和工作中。国内的AI大模型在过去几年里取得了显著的进展,不少独创的技术点和实际应用令人瞩目。 那么,国内的AI大模型有哪些独创的技术点?它们在实际应用中又有哪些出色表现呢?此外,普通人又该如何利用这些大模型提升工作和生活的质量和效率呢?本文将为你一一解析。 一、国内AI大模型的独创技术点 多模态学习 多