【在Linux世界中追寻伟大的One Piece】多路转接epoll
目录
1 -> I/O多路转接之poll
1.1 -> poll函数接口
1.2 -> poll的优点
1.3 -> poll的缺点
1.4 -> poll示例
1.4.1 -> 使用poll监控标准输入
2 -> I/O多路转接之epoll
2.1 -> 初识epoll
2.2 -> epoll的相关系统调用
2.2.1 -> epoll_create
2.2.2 -> epoll_ctl
2.2.3 -> epoll_wait
2.3 -> epoll工作原理
2.4 -> epoll优点
1 -> I/O多路转接之poll
1.1 -> poll函数接口
#include <poll.h>int poll(struct pollfd* fds, nfds_t nfds, int timeout);// pollfd 结构
struct pollfd
{int fd; /* file descriptor */short events; /* requested events */short revents; /* returned events */
};
参数说明:
- fds是一个poll函数监听的结构列表。每一个元素中,包含了三部分内容:文件描述符,监听的事件集合,返回的事件集合。
- nfds表示fds数组的长度。
- timeout表示poll函数的超时时间,单位是毫秒(ms)。
events和revents的取值:
事件 | 描述 | 是否可作为输入 | 是否可作为输出 |
POLLIN | 数据(包括普通数据和优先数据)可读 | 是 | 是 |
POLLRDNORM | 普通数据可读 | 是 | 是 |
POLLRDBAND | 优先级带数据可读(Linux不支持) | 是 | 是 |
POLLPRI | 高优先级数据可读,比如TCP带外数据 | 是 | 是 |
POLLOUT | 数据(包括普通数据和优先数据)可写 | 是 | 是 |
POLLWRNORM | 普通数据可写 | 是 | 是 |
POLLWRBAND | 优先级带数据可写 | 是 | 是 |
POLLRDHUP | TCP连接被对方关闭,或者对方关闭了写操作。它由GNU引入 | 是 | 是 |
POLLERR | 错误 | 否 | 是 |
POLLHUP | 挂起。比如管道的写端被关闭后,读端描述符上将收到POLLHUP事件 | 否 | 是 |
POLLNVAL | 文件描述符没有打开 | 否 | 是 |
返回结果:
- 返回值小于0,表示出错。
- 返回值等于0,表示poll函数等待超时。
- 返回值大于0,表示poll由于监听的文件描述符就绪而返回。
1.2 -> poll的优点
不同于select使用三个位图来表示三个fdset的方式,poll使用一个pollfd的指针实现。
- pollfd结构包含了要监视的event和发生的event,不再使用select"参数-值"传递的方式。接口使用比select更方便。
- poll并没有最大数量限制(但是数量过大后性能也是会下降)。
1.3 -> poll的缺点
poll中监听的文件描述符数目增多时:
- 和select函数一样,poll返回后,需要轮询pollfd来获取就绪的描述符。
- 每次调用poll都需要把大量的pollfd结构从用户态拷贝到内核中。
- 同时连接的大量客户端在一时刻可能只有很少的处于就绪状态,因此随着监视的描述符数量的增长,其效率也会线性下降。
1.4 -> poll示例
1.4.1 -> 使用poll监控标准输入
#include <poll.h>
#include <unistd.h>
#include <stdio.h>int main()
{struct pollfd poll_fd;poll_fd.fd = 0;poll_fd.events = POLLIN;for (;;) {int ret = poll(&poll_fd, 1, 1000);if (ret < 0) {perror("poll");continue;}if (ret == 0) {printf("poll timeout\n");continue;}if (poll_fd.revents == POLLIN) {char buf[1024] = { 0 };read(0, buf, sizeof(buf) - 1);printf("stdin:%s", buf);}}
}
2 -> I/O多路转接之epoll
2.1 -> 初识epoll
epoll是Linux内核中提供的一种高效的IO多路复用机制,它专为处理大量文件描述符而设计。相比于传统的select和poll机制,epoll在存在大量并发连接且只有少数连接活跃时,能够显著提高系统的CPU利用率。epoll的关键优势在于它在获取就绪事件时,不会遍历所有被监听的文件描述符集,而是只会遍历那些被设备IO事件异步唤醒(通过CPU中断机制)而加入就绪链表的文件描述符集。
按照man手册的说法:是为处理大批量句柄而作了改进的poll。
它是在2.5.44内核中被引进的(epoll(4)is a new API introduced in Linux kernel 2.5.44)它几乎具备了之前所说的一切优点,被公认为Linux2.6下性能最好的多路I/O就绪通知方法。
2.2 -> epoll的相关系统调用
2.2.1 -> epoll_create
int epoll_create(int size);
创建一个epoll的句柄。
- 自从linux2.6.8之后,size参数是被忽略的。
- 用完之后,必须调用close()关闭。
2.2.2 -> epoll_ctl
int epoll_ctl(int epfd, int op, int fd, struct epoll_event* event);
epoll的事件注册函数。
它不同于select()是在监听事件时告诉内核要监听什么类型的事件,而是在这里先注册要监听的事件类型。
- 第一个参数是epoll_create()的返回值(epoll 的句柄)。
- 第二个参数表示动作,用三个宏来表示。
- 第三个参数是需要监听的fd。
- 第四个参数是告诉内核需要监听什么事。
第二个参数的取值:
- EPOLL_CTL_ADD:注册新的fd到epfd中。
- EPOLL_CTL_MOD:修改已经注册的fd的监听事件。
- EPOLL_CTL_DEL:从epfd中删除一个fd。
struct epoll_event结构如下:
typedef union epoll_data
{void* ptr;int fd;uint32_t u32;uint64_t u64;
} epoll_data_t;struct epoll_event
{uint32_t events; //Epoll eventsepoll_data_t data; //User data variable
}_EPOLL_PACKED;
events可以是以下几个宏的集合:
- EPOLLIN:表示对应的文件描述符可以读(包括对端SOCKET正常关闭)。
- EPOLLOUT:表示对应的文件描述符可以写。
- EPOLLPRI:表示对应的文件描述符有紧急的数据可读(这里应该表示有带外数据到来)。
- EPOLLERR:表示对应的文件描述符发生错误。
- EPOLLHUP:表示对应的文件描述符被挂断。
- EPOLLET:将EPOLL设为边缘触发(Edge Triggered)模式,这是相对于水平触发(Level Triggered)来说的。
- EPOLLONESHOT:只监听一次事件,当监听完这次事件之后,如果还需要继续监听这个socket的话,需要再次把这个socket加入到EPOLL队列里。
2.2.3 -> epoll_wait
int epoll_wait(int epfd, struct epoll_event* events, int maxevents, int timeout);
收集在epoll监控的事件中已经发送的事件。
- 参数events是分配好的epoll_event结构体数组。
- epoll将会把发生的事件赋值到events数组中(events不可以是空指针,内核只负责把数据复制到这个events数组中,不会去帮助我们在用户态中分配内存)。
- maxevents告之内核这个events有多大,这个maxevents的值不能大于创建epoll_create()时的size。
- 参数timeout是超时时间(毫秒,0会立即返回,-1是永久阻塞)。
- 如果函数调用成功,返回对应I/O上已准备好的文件描述符数目,如返回0表示已超时, 返回小于0表示函数失败。
2.3 -> epoll工作原理
当某一进程调用epoll_create方法时,Linux内核会创建一个eventpoll结构体,这个结构体中有两个成员与epoll的使用方式密切相关。
struct eventpoll
{/*红黑树的根节点,这颗树中存储着所有添加到 epoll 中的需要监控的事件*/struct rb_root rbr;/*双链表中则存放着将要通过 epoll_wait 返回给用户的满足条件的事件*/struct list_head rdlist;
};
- 每一个epoll对象都有一个独立的eventpoll结构体,用于存放通过epoll_ctl方法向epoll对象中添加进来的事件。
- 这些事件都会挂载在红黑树中,如此,重复添加的事件就可以通过红黑树而高效的识别出来(红黑树的插入时间效率是lgn,其中n为树的高度)。
- 而所有添加到epoll中的事件都会与设备(网卡)驱动程序建立回调关系,也就是说,当响应的事件发生时会调用这个回调方法。
- 这个回调方法在内核中叫ep_poll_callback,它会将发生的事件添加到rdlist双链表中。
- 在epoll中,对于每一个事件,都会建立一个epitem结构体。
struct epitem
{struct rb_node rbn;//红黑树节点struct list_head rdllink;//双向链表节点struct epoll_filefd ffd; //事件句柄信息struct eventpoll* ep; //指向其所属的 eventpoll 对象struct epoll_event event; //期待发生的事件类型
}
- 当调用epoll_wait检查是否有事件发生时,只需要检查eventpoll对象中的rdlist双链表中是否有epitem元素即可。
- 如果rdlist不为空,则把发生的事件复制到用户态,同时将事件数量返回给用户。这个操作的时间复杂度是O(1)。
总结一下,epoll的使用过程就是三部曲:
- 调用epoll_create创建一个epoll句柄。
- 调用epoll_ctl,将要监控的文件描述符进行注册。
- 调用epoll_wait,等待文件描述符就绪。
2.4 -> epoll优点
- 接口使用方便:虽然拆分成了三个函数,但是反而使用起来更方便高效。不需要每次循环都设置关注的文件描述符,也做到了输入输出参数分离开。
- 数据拷贝轻量:只在合适的时候调用EPOLL_CTL_ADD将文件描述符结构拷贝到内核中,这个操作并不频繁(而select/poll都是每次循环都要进行拷贝)。
- 事件回调机制:避免使用遍历,而是使用回调函数的方式,将就绪的文件描述符结构加入到就绪队列中,epoll_wait返回直接访问就绪队列就知道哪些文件描述符就绪。这个操作时间复杂度O(1)。即使文件描述符数目很多,效率也不会受到影响。
- 没有数量限制:文件描述符数目无上限。
感谢各位大佬支持!!!
互三啦!!!
相关文章:

【在Linux世界中追寻伟大的One Piece】多路转接epoll
目录 1 -> I/O多路转接之poll 1.1 -> poll函数接口 1.2 -> poll的优点 1.3 -> poll的缺点 1.4 -> poll示例 1.4.1 -> 使用poll监控标准输入 2 -> I/O多路转接之epoll 2.1 -> 初识epoll 2.2 -> epoll的相关系统调用 2.2.1 -> epoll_cre…...

设计模式-参考的雷丰阳老师直播课
一般开发中使用的模式为模版模式策略模式组合,模版用来定义骨架,策略用来实现细节。 模版模式 策略模式 与模版模式特别像,模版模式会定义好步骤定义好框架,策略模式定义小细节 入口类 使用模版模式策略模式开发支付 以上使用…...

Python +Pyqt5 简单视频爬取学习(一)
文章目录 前言 一、演示 二、查找网页视频流的索引文件 三、分析视频流的url和视频流索引文件的差异性 四、判断视频数据是否需要转化为ts 五、判断视频是否被加密,如若被加密,需要先解密 六、合并所有的ts视频,以MP4模式输出完整视频 总结 前…...

Python Requests模块全面教程
Python Requests模块全面教程 在现代软件开发中,网络请求是一个不可或缺的部分。无论是获取网页数据、调用API接口,还是进行数据交互,都会涉及到HTTP请求。Python的Requests模块是一个非常强大的库,能够让我们轻松地发送HTTP请求…...

PyQt入门指南六十 与Python其他库的集成方法
PyQt是一个强大的GUI库,它可以与Python的其他库无缝集成,以实现更复杂的功能。以下是一些常见的集成方法和示例: 1. NumPy NumPy是Python中用于科学计算的基础库。您可以在PyQt应用程序中使用NumPy来处理数据和进行数值计算。 import sys …...

Android15之解决:Dex checksum does not match for dex:framework.jar问题(二百三十九)
简介: CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布:《Android系统多媒体进阶实战》🚀 优质专栏: Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏: 多媒体系统工程师系列【…...

车企自动驾驶功能策略 --- 硬件预埋(卷传感器配置)
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无利益不试图说服别人,是精神上的节…...

【已为网站上传证书,却显示不安全】
已为网站上传证书,却显示不安全 错误显示解决办法分析原因 错误显示 此站点有一个由受信任的颁发机构颁发的有效证书但是网站的某些部分不安全 解决办法 删除浏览器所有历史记录, 如果是Edge浏览器显示不安全,那就删除Edge浏览器的所有历史记录; 如果是Google Chrome浏览器显…...

docker busybox作为initContainers
一、上传到私有仓储 docker pull busybox:1.33.1 docker tag busybox:1.33.1 192.168.31.185/public/busybox:1.33.1 docker push 192.168.31.185/public/busybox:1.33.1 --- apiVersion: apps/v1 kind: Deployment metadata:annotations: {}labels: {}name: saas-ali-apiname…...

20.UE5UI预构造,开始菜单
2-22 开始菜单、事件分发器、UI预构造_哔哩哔哩_bilibili 目录 1.UI预构造 2.开始菜单和开始关卡 2.1开始菜单 2.2开始关卡 2.3将开始菜单展示到开始关卡 3.事件分发器 1.UI预构造 如果我们直接再画布上设计我们的按钮,我们需要为每一个按钮进行编辑&#x…...

Electron教程1-初学入门
玩转Electron Electron 是什么注意事项环境安装安装 vscode安装 git 第一个实例第二个实例第二个实例解读 总结问题解答 Electron 是什么 Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 嵌入 Chromium 和 Node.js 到 二进制的 Electron 允许您保持一个…...

从北美火到中国,大数据洞察品牌“STANLEY”的突围之路
保守直筒大头的“硬汉”外形,以百变颜色踩中时尚命脉,与各路大牌“梦幻联动”,不少时尚弄潮儿没能逃过其“真香”诱惑。 这就是今年以来从北美火到中国的STANLEY,在“巨无霸”水杯中突围出属于自己的一条路。 最近STANLEY又整活…...

深度学习之GAN应用
1 GAN的应用(文本生成) 1.1 GAN为什么不适合文本任务? GAN在2014年被提出之后,在图像生成领域取得了广泛的研究应用。然后在文本领域却一直没有很惊艳的效果。主要在于文本数据是离散数据,而GAN在应用于离散数据时…...

鸿蒙生态下的安全隐私保护:打造用户信任的应用体验
鸿蒙生态下的安全隐私保护:打造用户信任的应用体验 随着华为鸿蒙系统的快速发展,越来越多的设备开始支持这一操作系统,不仅限于智能手机,还包括智能穿戴设备、智能家居产品等。作为开发者,在享受鸿蒙生态系统带来的广…...

用pandoc工具实现ipynb,md,word,pdf之间的转化
Pandoc 是一个强大的工具,可以实现多种文件格式之间的转换,包括 Jupyter Notebook (.ipynb)、Markdown (.md)、Word (.docx)、PDF 等格式。以下是具体的实现方法: 1. 安装 Pandoc 确保已安装 Pandoc: Linux: sudo apt install p…...

第三十一天|贪心算法| 56. 合并区间,738.单调递增的数字 , 968.监控二叉树
目录 56. 合并区间 方法1:fff 看方法2:fff优化版 方法3: 738.单调递增的数字 968.监控二叉树(贪心二叉树) 56. 合并区间 判断重叠区间问题,与452和435是一个套路 方法1:fff 看方法2&am…...

力扣 最长公共前缀-14
最长公共前缀-14 class Solution { public:string longestCommonPrefix(vector<string>& strs) {//定义一个字符数组,用于存储strs字符串数组第一个字符串,方便与后面的字符串进行比较判断char s[200];//定义一个字符数组,用来返回…...

IDEA调整警告级别【IntelliJ IDEA 2024.2.0.1】
文章目录 目前现状鼠标悬停,选择配置筛选 > 取消选择OK效果 目前现状 需要把提示改成只要显示error的5个 鼠标悬停,选择配置 筛选 > 取消选择 OK 效果...

Vulnhub靶场 Billu_b0x 练习
目录 0x00 准备0x01 主机信息收集0x02 站点信息收集0x03 漏洞查找与利用1. 文件包含2. SQL注入3. 文件上传4. 反弹shell5. 提权(思路1:ssh)6. 提权(思路2:内核)7. 补充 0x04 总结 0x00 准备 下载链接&#…...

Essential Cell Biology--Fifth Edition--Chapter one (6)
1.1.4.4 Internal Membranes Create Intracellular Compartments with Different Functions [细胞膜形成具有不同功能的细胞内隔室] 细胞核、线粒体和叶绿体并不是真核细胞中唯一的膜包围细胞器。细胞质中含有大量的[ a profusion of]其他细胞器,这些细胞器被单层膜…...

Jupyter Book 快捷键总结大全
快捷键完整分类与功能 1. 模式切换 在 jb 中,您可以通过快捷键快速切换编辑模式和命令模式: 快捷键功能Esc切换到命令模式Enter切换到编辑模式 2. 单元格操作 单元格是 jb 的基本操作单位,以下快捷键可以帮助您快速编辑和管理单元格&…...

Spring Authorization Server OAuth2.1
Spring Authorization Server介绍 Spring Authorization Server 是一个框架,它提供了 OAuth 2.1 和 OpenID Connect 1.0 规范以及其他相关规范的实现。 它建立在 Spring Security 之上,为构建 OpenID Connect 1.0 身份提供者和 OAuth2 授权服务器产品提供…...

解决”重复文件名重命名“问题【根据Word系统方式】
提示:工作中遇到的功能需求,在此记录,不喜勿喷!谢谢 文章目录 前言一、需求分析二、需求实现 前言 最近工作中遇到的我认为有必要记录的需求实现,希望可以帮助到有同样需求的小伙伴们! 提示:以…...

【PyTorch】PyTorch Geometric(PyG)安装指南:如何高效配置图神经网络环境
目录 引言一、通过 Anaconda 安装二、通过 PyPi 安装三、从 Wheels 安装四、从 ROCm 安装五、从源代码安装5.1 确保 CUDA 环境设置正确5.1.1 检查 PyTorch 是否支持 CUDA5.1.2 设置 CUDA 环境变量5.1.3 验证 nvcc 是否可用 5.2 安装 PyTorch Geometric 所需软件包5.3 强制重新安…...

SolidWorks21装配体中一个零件无法改为线架图
右键零件弹出栏中选择零部件显示改为默认显示,再切换线架图,就会发现整个装配体都能切换为线架图了!...

11.11机器学习_介绍和定义
一、 机器学习介绍与定义 1. 机器学习定义 机器学习(Machine Learning)本质上就是让计算机自己在数据中学习规律,并根据所得到的规律对未来数据进行预测。 机器学习包括如聚类、分类、决策树、贝叶斯、神经网络、深度学习(Deep…...

【代码审计】常见漏洞专项审计-业务逻辑漏洞审计
❤️博客主页: iknow181 🔥系列专栏: 网络安全、 Python、JavaSE、JavaWeb、CCNP 🎉欢迎大家点赞👍收藏⭐评论✍ 0x01 漏洞介绍 1、 原理 业务逻辑漏洞是一类特殊的安全漏洞,业务逻辑漏洞属于设计漏洞而非实…...

SpringBoot单体服务无感更新启动,动态检测端口号并动态更新
SpringBoot单体服务无感更新启动 package com.basaltic.warn;import cn.hutool.core.io.IoUtil; import lombok.SneakyThrows; import org.apache.commons.lang3.StringUtils; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplic…...

CSS基础知识04
文本溢出通常是指在限定的空间内不能容纳所输入的文字,导致文字超出了容器的边界 一、文本溢出 1.1.css属性处理 所用到的属性 属性属性值overflowvisible:默认值,内容不会被修剪,会呈现在元素框之外。hidden:内容会…...

python程序对服务器cpu和内存资源占用的管理。
背景 在服务器上部署了一套目标检测的程序,做成while true 的轮询检测数据更新的定时任务。 结果没想到那台服务器还有一套可视化程序要给领导演示看,结果演示的时候平台各种报错。 然后通过top查看了一下资源利用率发现python的程序cpu 130。…...