Linux IO多路转接之epoll

文章目录

一、epoll初识

二、epoll的相关系统调用

1.epoll_create

2.epoll_ctl

3.epoll_wait

三、epoll工作原理

四、epoll的工作方式


本文主要介绍了epoll内部工作机制,如何达到高性能的多路转接。技术有限,如有错误请指正。参考文献:深入揭秘 epoll 是如何实现 IO 多路复用的


一、epoll初识

按照man手册:epoll是为处理大批量句柄而改进的poll,被公认为linux2.6下性能最好的io就绪通知方法

二、epoll的相关系统调用

epoll有三个相关调用

1.epoll_create

int epoll_create(int size);

创建一个epoll句柄,从Linux2.6.8之后,size参数是被忽略的,设置为>0即可。

用完之后,必须调用close()关闭

2.epoll_ctl

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

epoll的事件注册函数

  • 它不同于select()是在监听事件时告诉内核要监听什么类型的事件,而是在这里先注册要监听的事件类型
  • epfd是创建的返回值
  • 第二个参数表示动作,用三个宏来表示:EPOLL_CTL_ADD注册新的fd到epfd中 ;EPOLL_CTL_MOD修改已经注册的fd监听事件; EPOLL_CTL_DEL:从epfd中删除一个fd
  • 第三个参数是需要监听的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_data_t data;} __EPOLL_PACKED;
  • events可以是几个宏的集合:
    EPOLLIN:表示对应的fd可以读(包括对端SOCKET正常关闭)
    EPOLLOUT:表示对应的fd可以写
    EPOLLPRI:表示对应的fd有紧急的数据可读(这里对应表示有带外数据到来)
    EPOLLERR:表示对应的fd描述符发生错误
    EPOLLHUP:表示对应的fd被挂断
    EPOLLET:将epoll设置为边缘触发(et),这是相对于水平触发(lt)来说的
    EPOLLONESHOT:只监听一次事件,当监听完这次事件后,如果还需要继续监听socket的话,需要再次把这个socket加入到epoll队列中

3.epoll_wait

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

收集在epoll监控的事件中已经发送的事件

  • 参数events是分配好的epll_event结构体数组
  • epoll将会把发生的事件赋值到events数组中(events不可以是空指针,内核只负责把数据复制到这个events数组中,不会去帮助我们在用户态中分配内存)
  • maxevents告知内核这个events有多大,这个Maxevnets的值不能大于创建epoll_create()时的size
  • 参数timeout是超时事件(ms,0会立即返回,-1永久阻塞)
  • 函数调用成功,返回对应io上已经准备好的fd数目,如返回0表示已经超时,返回小于0表示函数失败

三、epoll工作原理

struct eventpoll
{/* 红黑树的根节点,这棵树中存储着所有添加到epoll当中需要监控的事件*/struct rb_tree;struct list_head rdlist;
};

每一个epoll对象都有一个独立的eventpoll结构体,用于存放通过epoll_ctl方法向epoll对象中添加进来的事件

这些事件都会挂载在红黑树中,如此重复添加的事件就可以通过红黑树而高效的识别出来(红黑树的插入效率是logn,其中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的优点

  • 接口使用方便:虽然拆分成了三个函数,但是使用起来更高效,不需要每次循环都设置关注的fd,也做到了输入输出参数分离
  • 数据拷贝轻量:只在合适的时候调用EPOLL_CTL_ADD将fd拷贝到内核中,这个操作并不频繁(而select,poll每次都需要进行拷贝)
  • 事件回调机制:避免使用遍历,而是使用回调函数的方式,将就绪的fd结构加入到就绪队列中,epoll_wait返回直接访问就绪队列就知道哪些fd就绪,这个操作事件复杂度O(1),即使fd很多,效率也不会收到影响
  • 没有数量限制,文件描述符数目无上限

有的地方说,epoll使用了内存映射机制,内存映射机制是:内核直接将就绪队列通过mmap的方式映射到用户态,避免了拷贝内存这样的额外性能开销。这种说法是不准确的,我们定义的struct epoll_evnet是我们在用户空间中分配好的内存,势必还是需要将内核中的数据结构拷贝到这个用户空间的内存中的。

四、epoll的工作方式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/198929.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Redis】Redis 的学习教程(十三)Redis 各场景

由于Redis 支持比较丰富的数据结构&#xff0c;因此他能实现的功能并不仅限于缓存&#xff0c;而是可以运用到各种业务场景中&#xff0c;开发出既简洁、又高效的系统 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-bo…

第三节:提供者、消费者、Eureka

一、 提供者 消费者&#xff08;就是个说法、定义&#xff0c;以防别人叭叭时听不懂&#xff09; 服务提供者&#xff1a;业务中被其他微服务调用的服务。&#xff08;提供接口给其他服务调用&#xff09;服务消费者&#xff1a;业务中调用其他微服务的服务。&#xff08;调用…

QThread之moveToThread用法

简介 使用moveToThread函数的流程如下&#xff1a; 1、创建一个类继承自QObject类或其子类&#xff0c;并在其中定义所要执行的多个任务&#xff0c;执行多个任务就要定义相应的信号。 2、任务通过moveToThread指定所要执行的线程。 3、线程通过start启动 4、通过信号与槽机制…

【AI绘画】万字长文——(超详细)ControlNet的详细介绍使用Stable Diffusion的艺术二维码完全生成攻略

目录 前言一、名词解释1-1、Stable Diffusion介绍1-2、ControlNet介绍1-2-1、ControlNet介绍&工作原理1-2-2、ControlNet控制方法介绍 1-3、案例分析1-3-1、室内装修设计1-3-2、品牌创意海报 1-4、stable-diffusion-webui 的参数解释 二、生成方法2-1、图像到图像2-1-1、二…

Python使用netmiko配置华为交换机

一、netmiko介绍 1.更适合网络设备的自动化运维模块。 二、场景 1、批量查询 2、批量配置变更、备份 三、项目地址 GitHub - ktbyers/netmiko: Multi-vendor library to simplify Paramiko SSH connections to network devices 三、使用步骤 1.安装netmiko pip install ne…

D6208单片双向马达驱动电路国产芯片,工作电源电压范围宽(4.5V~15.0V),内设保护二极管采用SOP8封装

D6208 是一块单片双向马达驱动电路&#xff0c;它使用TTL电平的逻辑信号就能控制卡式录音机和其它电子设备中的双向马达。该电路由一个逻辑部分和一个功率输出部分组成。逻辑部分控制马达正、反转向及制动&#xff0c;功率输出部分根据逻辑控制能提供100mA&#xff08;典型值&a…

腾讯地图系列(二):微信小程序添加插件(三种方法)以及插件AppId获取

目录 第一章 前言 第二章 添加插件 2.1 微信小程序添加插件方法一&#xff08;微信公众平台添加插件&#xff09; 2.2 微信小程序添加插件方法二&#xff08;通过项目配置添加插件&#xff09; 2.3 微信小程序添加插件方法三&#xff08;微信公众平台服务市场添加插件&…

spring mvc理解

spring mvc M&#xff1a;model 模型 V&#xff1a;view 视图 C&#xff1a;controller 控制器 S: service 服务处理 D: Dao 数据持久化 视图 我理解就是web页面&#xff0c;帮助用户调用后端接口。 前后端分离之后&#xff0c;view似乎就和后端没什么关系了。 模型 格式…

zabbix6.4监控交换机发现ICMP报错Ping item must have target or host interface specified

报错信息&#xff1a; 查看监控项&#xff1a; 修改键值&#xff1a; 保存再次检查&#xff0c;发现又报错/usr/sbin/fping: [2] No such file or directory 原因是&#xff0c;zabbix-server上没有安装fping工具 解决方法&#xff1a;yum install fping -y 之后数据采集正常…

【unity3D】Transform组件(如何访问和获取Transform组件)

&#x1f497; 未来的游戏开发程序媛&#xff0c;现在的努力学习菜鸡 &#x1f4a6;本专栏是我关于游戏开发的学习笔记 &#x1f236;本篇是unity的Transform组件 Transform组件 基础知识介绍三个成员变量常用属性扩展 Transform的相关查找方法静态方法 基础知识 介绍 在Unit…

mapbox实现框选要素

成果图 参考博客 https://blog.csdn.net/ScapeD/article/details/89158755 原理与源码 利用mapbox的queryRenderedFeatures方法可以获取范围内的要素&#xff0c;但是这个只能是点和矩形和范围内的全屏要素&#xff0c;并不支持多边形&#xff0c;所以实现这个的思路就是画完框…

【JavaEE进阶】 Spring核⼼与设计思想

文章目录 &#x1f332;Spring 是什么&#xff1f;&#x1f384;什么是IoC呢&#xff1f;&#x1f388;传统程序开发&#x1f388;传统程序开发的缺陷&#x1f388;如何解决传统程序的缺陷&#xff1f;&#x1f388;控制反转式程序开发&#x1f388;对⽐总结规律 &#x1f340;…

适用于 Windows 的最佳(免费/付费)数据恢复软件

借助最佳数据恢复工具从 Windows PC 恢复丢失和删除的数据 您是否正在寻找一种巧妙的方法来从计算机中取消删除或恢复已删除的文件&#xff1f;如果是&#xff0c;那么这篇文章就是为您准备的&#xff01;在本教程中&#xff0c;我们整理了一份全面的数据恢复软件列表&#xf…

机器人学习目标

学习目标&#xff1a; 若干年后&#xff0c;我们都将化为尘土&#xff0c;无人铭记我们的存在。那么&#xff0c;何不趁现在&#xff0c;尽己所能&#xff0c;在这个世界上留下一些痕迹&#xff0c;让未来的时光里&#xff0c;仍有人能感知到我们的存在。 机器人协会每届每个阶…

外包干了4年,技术退步明显...

先说情况&#xff0c;大专毕业&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试&#xf…

postgres pg_dump: fe_sendauth: no password supplied问题处理

postgres pg_dump: fe_sendauth: no password supplied问题处理 1、pg_dump: fe_sendauth: no password supplied问题处理&#xff08;root 用户&#xff09;2、解决方法2.1、创建 .pgpass文件2.2、chmod 600 ~/.pgpass 3、额外情况 1、pg_dump: fe_sendauth: no password supp…

文件重命名:删除文件名中的空格,提高文件可读性和可管理性的方法

在计算机科学中&#xff0c;有效的文件管理对于提高工作效率和保持数据的一致性至关重要。工作中经常会遇到文件名中包含空格的情况&#xff0c;这不仅会使文件在某些情况下难以读取&#xff0c;而且可能导致管理上的困扰。在文件名中添加空格可能会使文件名变得模糊和不明确&a…

我有才知识付费小程序免费搭建:轻松拥有知识付费平台

用户管理 提供会员特权和积分奖励&#xff0c;提高用户忠诚度和购买力。 用户通过在平台上进行消费、签到、参与活动等方式获取积分&#xff0c;用于兑换丰厚奖品或提升会员等级。增强用户的参与感与忠诚度&#xff0c;提高用户粘性&#xff0c;并刺激用户的购买力。 为用户打…

Arduino学习笔记2023年11月30日

目录 1 编程软件下载2 代码结构3 IO引脚控制3.1 引脚初始化3.2 引脚使用数字量输出数字量输入模拟量输出模拟量输入 4 串口串口初始化串口输出串口输入 5 外部中断6 函数6.1 映射区间函数6.2 延时函数 总结 1 编程软件下载 官网链接&#xff1a;https://www.arduino.cc/ 下载链…

SpringBoot 配置文件使用@ @取值

目录 一、背景 二、遇到的问题 三、解决办法 一、背景 &#xff08;1&#xff09;我在项目中引入了如下依赖&#xff0c;目的是开启SpringBoot为我们提供的监控(Actuator)功能。 <!-- 引入SpringBoot 监控功能 --> <dependency><groupId>org.springframew…