NIO原理浅析(三)

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.mzph.cn/news/69577.shtml

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

相关文章

Kotlin 环境下解决属性初始化问题

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

react使用hook封装一个tab组件

目录 react使用hook封装一个tab组件Tabbar.jsx使用组件效果 react使用hook封装一个tab组件 Tabbar.jsx import PropsTypes from "prop-types"; import React, { useEffect, useState } from react; export default function Tabbar(props) {const { tabData , cur…

使用pip下载第三方软件包报错超时处理方法

报错如下&#xff1a; WARNING: Retrying (Retry(total4, connectNone, readNone, redirectNone, statusNone)) after connection broken by ‘ReadTimeoutEr ror(“HTTPSConnectionPool(host‘files.pythonhosted.org’, port443): Read timed out. (read timeout15)”)’: /p…

Maven编译java及解决程序包org.apache.logging.log4j不存在问题

1、首先新建一个文件夹&#xff0c;比如hello Hello里新建pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi…

git快速使用

1、下载git 设置签名 2、基本概念 工作区&#xff1a;写代码的地方。 暂存区&#xff1a;.git的.index 工作区&#xff1a;.git 3、常用操作 本地codinggit init&#xff0c; 初始化一个本地仓库&#xff0c;项目根目录下会出现个.gitgit remote add origin gitgithub.com…

[杂谈]-快速了解LoRaWAN网络以及工作原理

快速了解LoRaWAN网络以及工作原理 文章目录 快速了解LoRaWAN网络以及工作原理1、LoRaWAN网络元素1.1 终端设备&#xff08;End Devices&#xff09;1.2 网关&#xff08;Gateways&#xff09;1.3 网络服务器&#xff08;Net Server&#xff09;1.4 应用服务器&#xff08;Appli…

OpenCV(二十一):椒盐噪声和高斯噪声的产生

目录 1.图像噪声介绍 2.椒盐噪声的产生 3.高斯噪声的产生 1.图像噪声介绍 噪声介绍 图像噪声是指在图像中存在的不期望的、随机的像素值变化&#xff0c;这些变化来源于多种因素。噪声可能导致图像细节模糊、失真或难以分辨。 以下是几种常见的图像噪声类型&#xff1a; 1…

Unity中神秘的Transform和transform(小写)的关系

1.为什么Transform类是保护的不能通过new 来实例化对象,也没有静态函数,而Rotate()这种方法却属于它,该如何访问? Transform 类还是被保护的不允许用户修改! protected Transform(); 是一个受保护的构造函数,不能直接实例化 Transform 类。 2.为甚么transform可以访问Tr…

Mac Homebrew中常用的 Brew 命令

Mac 中常用的 Brew 命令集 Brew&#xff08;Homebrew&#xff09;是一个强大的包管理器&#xff0c;用于在 macOS 上安装、更新和管理各种软件包。它使得在 Mac 上安装开发工具、应用程序和库变得轻松和便捷。本博客将介绍一些在 Mac 中常用的 Brew 命令&#xff0c;以帮助您更…

【Springcloud】Sentinel熔断和降级

【Springcloud】Sentinel熔断和降级 【一】基本介绍【1】什么是熔断和降级【2】为什么使用熔断和降级【3】Sentinel熔断和降级【4】核心概念 【二】下载方式【1】Windows平台安装包下载【2】打开控制台 【三】使用案例【1】添加依赖【2】添加Sentinel配置【3】添加TestUserCont…

线上问诊:数仓开发(一)

系列文章目录 线上问诊&#xff1a;业务数据采集 线上问诊&#xff1a;数仓数据同步 线上问诊&#xff1a;数仓开发(一) 文章目录 系列文章目录前言一、Hive on yarn二、数仓开发1.ODS开发2.DIM开发3.DWD开发 总结 前言 上次我们已经将MYSQL的数据传送到了HDFS&#xff0c;但…

commet与websocket

commet与websocket Comet 前言 Comet是一种用于web的技术&#xff0c;能使服务器能实时地将更新的信息传送到客户端&#xff0c;而无须客户端发出请求&#xff0c;目前有两种实现方式&#xff0c;长轮询和iframe流。 实现方式 长轮询 长轮询是在打开一条连接以后保持&…

关于HarmonyOS元服务的主题演讲与合作签约

一、感言 坚持中&#xff0c;总会有很多意想不到的收获。 前几次参与HDC时更多的是观众、开发者、专家的身份&#xff0c;以参观、学习、交流为主。 通过几年的努力&#xff0c;和HarmonyOS功能成长&#xff0c;在2023年的HDC大会中&#xff0c;有了我的演讲&#xff0c;并带领…

无涯教程-Android Mock Test函数

本节介绍了与 Android 相关的各种模拟测试。您可以在本地计算机上下载这些样本模拟测试,并在方便时离线解决。每个模拟测试均随附一个模拟测试键,可让您验证最终分数并为自己评分。 Mock Test I Mock Test II Mock Test III Mock Test IV Q 1 -什么是Android&#xff1f; A -A…

VMware虚拟机安装CentOS6.9设置静态ip

1.设置虚拟网络编辑器 点击编辑–>虚拟网络编辑器 2.更改系统网络适配器选项 这里的子网掩码与网关&#xff0c;与第一步的一致 3.修改虚拟机主机名 vi /etc/sysconfig/networkNETWORKINGyue HOSTNAMEchen4.配置IP映射 vi /etc/hosts192.168.121.138 chen5.配置网卡…

PyQt5报错Process finished with exit code -1073740791 (0xC0000409)

点击按钮之后&#xff0c;就直接退出程序&#xff0c;控制台出现一个提示&#xff1a;解决办法&#xff1a; 在PyCharm中打开Run菜单&#xff0c;找到Edit Configurations进入&#xff0c;勾选Emulate terminal in output console即可。 然后再运行一下程序&#xff0c;就可以…

Sublime Text汉化,主打简单明了

在Sublime中设置中文的步骤如下&#xff1a; 1.打开Sublime Text&#xff0c;使用快捷键ShiftCtrlP&#xff08;MacOS下cmdShiftP&#xff09;&#xff0c;弹出查找栏。 2.在搜索框中输入关键字"install"&#xff0c;出现下拉选项&#xff0c;点击选择其中的"P…

Cmake qt ,vtkDataArray.cxx.obj: File too big

解决方法&#xff1a; Qt4 在pro 加入“QMAKE_CXXFLAGS -BigObj” 可以解决 Qt5 在网上用“-Wa,-mbig-obj” 不能解决&#xff0c;最后通过“QMAKE_CXXFLAGS -Ofast -flto”解决问题。 Qt4 在pro 加入“QMAKE_CXXFLAGS -BigObj” 可以解决Qt5 在网上用“-Wa,-mbig-obj” …

视频集中存储/云存储/磁盘阵列/视频监控管理平台EasyCVR接入海康SDK后视频播放崩溃的问题排查

视频集中存储/云存储/磁盘阵列/视频监控管理平台EasyCVR可支持海量视频的轻量化接入与汇聚管理。在视频能力上&#xff0c;EasyCVR可实现视频直播、云端录像、检索与回放、云存储、告警上报、语音对讲、电子地图、H.265视频自动转码、服务器集群、AI智能分析接入以及平台级联等…

TDesign文档中复制的图标代码用不了 不知道tdesign-icons-vue中有哪些可用组件 解决办法

今天想找个检索的图标 结果发现tdesign的官网真的 图标这里写的挺不友好的 这里很多图标代码直接通过tdesign-icons-vue包去引入 甚至都找不到 其实也很简单 大部分开发工具 对这里路径 都可以直接 按住Ctrl 然后点击进入 进来之后 这些包 我们再按着Ctrl 继续往下找 特别是…