NIO原理浅析(三)

news2024/11/29 1:39:46
epoll

首先认识一下epoll的几个基础函数

int s = socket(AF_INET, SOCK_STREAM, 0);
bind(s, ...);
listen(s, ...);

int epfd = epoll_create(...)
epoll_ctl(epfd, ...); //将所有需要监听的socket添加到epfd中

while(1) {
    int n = epoll_wait(...);
    for(接受到数据的socket) {
      //处理数据
    }
}

这段代码涉及到几个与epoll相关的函数方法:

  • epoll_create: 创建一个文件句柄

  • epoll_ctl: 向epoll对象添加/修改/删除要管理的连接

  • epoll_wait: 等待其管理的连接上的IO事件

1、epoll_create
int epoll_create(int size);

功能描述:用于生成一个epoll专用的文件描述符

参数size:因为epoll底层使用红黑树来保存文件描述符,红黑树的查找时间复杂度为O(logN),这个size并没有必要限制大小。size可以设置为大于0的任何数。

返回值:如果成功,返回epoll专用的文件描述符,如果失败,则返回-1。

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

epoll中的事件注册函数,用于注册要监听的事件类型

参数

  • epfd: epoll专用的文件描述符,epoll_create()的返回值

  • op: 表示动作,用三个宏来表示:

    • EPOLL_CTL_ADD: 注册新的fd到epfd中

    • EPOLL_CTL_MOD: 修改已经注册的fd的监听事件

    • EPOLL_CTL_DEL: 从epfd中删除一个fd

  • fd: 需要被监听的文件描述符

  • event: 告诉内核需要监听什么事件

  • 返回值:0表示成功,-1表示失败

epoll_event结构体如文档描述:

       #include <sys/epoll.h>

       struct epoll_event {
           uint32_t      events;  /* Epoll events */
           epoll_data_t  data;    /* User data variable */
       };

       union epoll_data {
           void     *ptr;
           int       fd;
           uint32_t  u32;
           uint64_t  u64;
       };

       typedef union epoll_data  epoll_data_t;

events可以是以下几个宏的集合:

  • EPOLLIN: 表示对应的文件描述符可以读

  • EPOLLOUT:表示对应的文件描述符可以写

  • EPOLLPRI:表示对应的文件描述符有紧急的数据可以读

  • EPOLLERR: 表示对应的文件描述符发生错误

  • EPOLLHUP:表示对应的文件描述符被挂断

  • EPOLLET: 将EPOLL设为边缘触发模式,不设置为水平触发模式

  • EPOLLONESHOT: 只监听一次事件,当监听完这次事件之后,如果还需要监听这次事件,则需要把socket重新加入到EPOLL中。

3、epoll_wait
int epoll_wait(int epfd, struct epoll_event * event, 
               int maxevents, int timeout);

功能:本函数用于监控事件的发生,当epoll监控的事件中存在已经发送的事件,那么就可以将此事件收集起来。

参数:

  • epfd:epoll自身产生的文件描述符,调用epoll_create的返回值

  • event:事先必须将空间分配好的结构体数组,epoll将即将发生的事件赋值到event数组中。

  • maxevents:告诉内核共有多少个event数组的大小

  • timeout:超时时间,单位为毫秒,设为-1时,该函数状态为阻塞。

  • 返回值:如果为-1,表示失败;如果为0,表示已经超时;如果成功,返回需要处理的事件数目。

epoll整体流程图如下所示:

在这里插入图片描述

我们在之前文章中讨论过,select和poll存在三个缺陷,epoll方式很好的解决了这些问题:

epoll在内核中使用红黑树这个数据结构来保存文件描述符,红黑树这个数据结构的增删改的时间复杂度为O(logn),select/poll每次监听套接字,都需要将套接字列表整个复制到内核态,而epoll使用epoll_ctl,每次将一个监听套接字复制到内核态,这明显减少了用户空间到内核态的大量数据拷贝和内存分配。

epoll使用异步回调的机制,内核态维护一个就绪队列,如果某个socket已经准备好,那么就会通过回调函数触发内核将socket事件加入到就绪事件列表。用户调用epoll_wait函数,就会返回有事件发生的文件描述符的个数。这个过程中,没有像select/poll一样对socket集合进行了O(N)时间复杂度的轮询。提高了检测的效率。

边缘触发和水平触发

epoll支持两种事件触发模式:

  • 边缘触发:当被监控的Socket描述符有可读事件发生时,服务器端在调用epoll_wait这个函数时,只会苏醒一次,然后从内核缓冲区中读取所有的数据

  • 水平触发:当被监控的Socket描述符有可读事件发生时,服务器端在调用epoll_wait这个函数时,会不断的苏醒,直到内核中没有数据可读才停止苏醒。

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

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

相关文章

el-table 垂直表头

效果如下&#xff1a; 代码如下&#xff1a; <template><div class"vertical_head"><el-table style"width: 100%" :data"getTblData" :show-header"false"><el-table-columnv-for"(item, index) in getHe…

【javascript】禁止浏览器调试前端页面

目录 为啥要禁止&#xff1f;无限 debugger基础禁止调试解决对策 为啥要禁止&#xff1f; 由于前端页面会调用很多接口&#xff0c;有些接口会被别人爬虫分析&#xff0c;破解后获取数据&#xff0c;为了杜绝这种情况&#xff0c;最简单的方法就是禁止人家调试自己的前端代码 …

成都瀚网科技有限公司:抖店怎么开通直播?

随着互联网和移动支付的快速发展&#xff0c;越来越多的人选择开设自己的抖音商店。抖音作为国内最受欢迎的短视频平台之一&#xff0c;拥有庞大的用户基础&#xff0c;成为众多创业者青睐的平台。那么&#xff0c;如何经营自己的抖音店铺呢&#xff1f;下面将从几个方面为您介…

C# 中什么是重写(子类改写父类方法)

方法重写是指在继承关系中&#xff0c;子类重新实现父类或基类的某个方法。这种方法允许子类根据需要修改或扩展父类或基类的方法功能。在面向对象编程中&#xff0c;方法重写是一种多态的表现形式&#xff0c;它使得子类可以根据不同的需求和场景提供不同的方法实现。 方法重…

设计实现QSPI Flash的下载算法

mm32-2nd-bootloader技术白皮书&#xff08;3&#xff09;——设计实现QSPI Flash的下载算法 mm32-2nd-bootloader技术白皮书&#xff08;3&#xff09;——设计实现QSPI Flash的下载算法 | MCU加油站 cathy 发布于&#xff1a;周一, 03/20/2023 - 15:29 &#xff0c;关键词&a…

变压器智能在线监测

变压器智能在线监测是一种先进的变压器状态监测方式&#xff0c;采用了先进的技术手段&#xff0c;能够对变压器运行状态进行实时、在线、自动的监测和分析。可以在变压器运行过程中&#xff0c;对其电压、电流、温度、局放等参数进行实时监测&#xff0c;及时发现异常情况并进…

为何跨境界如此看重黑色星期五?这一点是关键

黑色星期五通常会利用折扣和独一无二的优惠为电子商务商店带来大量新客户。黑色星期五可能会给您的在线商店带来丰厚的利润&#xff0c;如果无法留住这些客户&#xff0c;您就会损失巨大。通过对电子商务客户服务策略进行一些调整&#xff0c;您可以将这些黑色星期五客户转变为…

2023最新多功能XL软件库APP源码+PHP后端系统源码/功能强大/软件库自带后台管理系统

2023最新多功能XL软件库APP源码PHP后端系统源码/功能强大/软件库自带后台管理系统31xl软件库最新可以正常使用版: https://url11.ctfile.com/d/25976711-57801726-b66bb0?p6724 &#xff08;访问密码&#xff1a;6724&#xff09; 多功能软件库&#xff0c;支持自定义对接易支…

LiveGBS流媒体平台GB/T28181功能-支持数据库切换为高斯数据库信创瀚高数据信创数据库

LiveGBS流媒体平台GB/T28181功能-支持数据库切换为高斯数据库信创瀚高数据信创数据库 1、如何配置切换高斯数据库&#xff1f;2、如何配置切换信创瀚高数据库&#xff1f;3、搭建GB28181视频直播平台 1、如何配置切换高斯数据库&#xff1f; livecms.ini -> [db]下面添加配…

JavaScript - 好玩的打字动画

效果预览&#xff1a; &#x1f680;HTML版本 <!DOCTYPE html> <html> <head><title>打字动画示例</title><style>.typewriter {color: #000;overflow: hidden; /* 隐藏溢出的文本 */white-space: nowrap; /* 不换行 */border-right: .…

macOS通过钥匙串访问找回WiFi密码的详细教程

如果您忘记了Mac电脑上的WiFi密码&#xff0c;可以通过钥匙串访问来找回它。具体步骤如下&#xff1a; 1.打开Mac电脑的“启动台”&#xff0c;然后在其他文件中找到“钥匙串访问”。 2.运行“钥匙串访问”应用程序&#xff0c;点击左侧的“系统”&#xff0c;然后在右侧找到…

FT232RL国产替代芯片GP232RL无需软硬件修改资料

GP232RL是最新加入 ftdi 系列 usb 接口集成电路设备的设备。 GP232RL是一个 usb 到串行 uart 接口&#xff0c;带有可选的时钟发生器输出&#xff0c;以及新的 ftdichip-idTM 安全加密器特性。此外&#xff0c;还提供了异步和同步位崩接口模式。 通过将外部 eeprom、时钟电路和…

Android Studio更新新版本后无法创建flutter项目

最新更新了AndroidStudio版本&#xff0c;发现无法创建flutter项目。 dart和flutter插件确认都已安装&#xff0c;该有的环境配置都已配置。 最后与同事的插件作比较发现是Android APK Support这个插件没勾选。 勾选后&#xff0c;点击右下角的apply&#xff0c;重启AndroidS…

vue+elementUI el-select 自定义搜索逻辑(filter-method)

下拉列表的默认搜索是搜索label显示label,我司要求输入id显示label名称 <el-form-item label"部门&#xff1a;"><el-select v-model"form.region1" placeholder"请选择部门" filterable clearable:filter-method"dataFilter&qu…

手写apply方法

<script>/** 手写apply方法 * */Function.prototype.myApply function (context, args) {console.log(this, sss)//fnconst key Symbol()context[key] thiscontext[key](...args)delete context[key]return context[key]}const obj {name: zs,age: 18}function fn …

保姆级 C++ 学习路线

上周有小伙伴留言求安排一手C/C学习路线&#xff0c;这周一份保姆级的C语言安排上&#xff01; 以前就写过C语言的学习路线&#xff1a;可能是北半球最好的零基础C语言学习路线&#xff0c;这次把C的学习路线也安排上&#xff0c;专门花了一个多月写了这篇学习路线&#xff0c;…

风控引擎如何快速添加模型,并实时了解运行状态?

目录 风控模型的主要类型 风控引擎如何管理模型&#xff1f; 模型就是基于目标群体的大规模采样数据&#xff0c;挖掘出某个实际问题或客观事物的现象本质及运行规律&#xff0c;利用抽象的概念分析存在问题或风险&#xff0c;计算推演出减轻、防范问题或风险的对策过程&…

【MySql】数据库的CRUD(增删查改)

写在最前面的话 哈喽&#xff0c;宝子们&#xff0c;今天给大家带来的是MySql数据库的CRUD&#xff08;增删改查&#xff09;&#xff0c;CRUD是数据库非常基础的部分&#xff0c;也是后端开发日常工作中最主要的一项工作&#xff0c;接下来让我们一起进入学习吧&#xff0c;感…

如何指定this

<script>/*如何指定this的值可以通过2类方法指定1.调用时指定1.1call方法1.2apply方法2.创建时指定2.1bind方法2.2箭头函数*/// ------1.调用时指定------//1.1call方法:挨个传入参数//1.2apply方法:数组形式传入参数function foo (numA, numB) {console.log(this)consol…

10个最强大的AI驱动的3D建模工具【生成式AI】

推荐&#xff1a;用 NSDT编辑器 快速搭建可编程3D场景 在快速发展的技术世界中&#xff0c;人工智能 (AI) 已经改变了游戏规则&#xff0c;尤其是在 3D 对象生成领域。 AI 驱动的 3D 对象生成器彻底改变了我们创建和可视化 3D 模型的方式&#xff0c;使该过程更加高效、准确且可…