计算机网络【EPoll原理】

news2025/1/23 15:06:19
预备知识:内核poll钩子原理
内核函数poll_wait

把当前进程加入到驱动里自定义的等待队列上 ;

当驱动事件就绪后,就可以在驱动里自定义的等待队列上唤醒调用poll的进程;

故poll_wait作用:可以让驱动知道事件就绪的时候唤醒哪些等待进程;

钩子poll

内核f_op->poll必须配合驱动自己的等待队列才能用,不然驱动有事件产生后不知道哪些进程调用了poll来等待这个事件。

内核f_op->poll要做的事情。

  • 调用poll_wait,将当前进程放入驱动设备的等待队列上,这样驱动就知道哪些进程在调用poll等待事件。
  • 检查此时立刻已有的事件(POLLIN\POLLOUT\POLLERR…)并返回掩码表示。

f_op->poll是一个非阻塞的操作,立即返回,返回值以掩码形式表示当前已产生的事件集合。

预备知识:等待队列

等待队列对头:wait_queue_head_t ;

队列的成员:wait_queue_t;

wait_queue_t的成员:

void *private; /*指向进程描述符task_struct*/    
wait_queue_func_t  func;//唤醒时调用此函数,即钩子函数    
struct list_head  task_list;//队列链表指针

一般钩子函数func是内核默认函数default_wake_function,功能就是唤醒了进程。

我们也可以在把进程放入等待队列时主动设定钩子函数,使得在唤醒进程时自动执行我们需要的操作。

epoll就利用了队列钩子函数:把产生的事件内容copy到rdlist 。这样,事件来临时会自动把事件内容放到rdlist中,而不需要我们自己遍历监听句柄们查有谁产生了事件。

调用epoll_create1/epoll_create

创建了epoll句柄eventpoll,返回其文件表示的描述符epfd。

img

eventpoll内部有以下关键数据结构:

  • rbtree:红黑树,每个被加入到epoll监控的文件事件会创建一个epitem结构,作为rbtree节点 。

​ 使用rbtree的优点:可容纳大量文件事件,方便增删改(O(logN))。

  • rdlist:内核链表,用于存放当前产生了期待事件产生的文件句柄们(这里的一个文件句柄可以理解为一个epoll_event)。

  • wq:当进程调用epoll_wait等待时,进程加入等待队列wq。

  • poll_wait:eventpoll本身的等待队列,由于eventpoll自己也被当做文件,这个队列用于自己被别人调用select/poll/epoll监听的情况(一般没啥用)。

poll_wait在啥时候用呢:

fd = socket(...);
efd1 = epoll_create();
efd2 = epoll_create();
epoll_ctl(efd1, EPOLL_CTL_ADD, fd, ...);
epoll_ctl(efd2, EPOLL_CTL_ADD, efd1, ...);

如上,efd1监控fd,而efd2监控了efd1,即嵌套的epoll监控:epoll监控另一个epoll句柄

efd2要监控efd1,将调用efd1的poll函数

回忆之前说过:文件f_op->poll需要配合驱动提供的等待队列

对于epollfd,等待队列就是poll_wait

efd2监听efd1,会调用efd1->f_op->poll,于是把当前进程放到efd1的poll_wait队列上

在epoll的内核实现中,当efd1本身监听到fd事件产生后,会顺便唤醒poll_wait上的进程

于是,“efd1监听到事件” 被通知到efd2。这样,就实现了epollfd被其他多路复用监听了!

故:poll_wait就是用于epoll句柄被另外的多路复用监听的,配合epoll自己的f_op->poll,看起来一般用不到

调用epoll_ctl操作句柄新增监控事件

epoll_ctl:EPOLL_CTL_ADD、EPOLL_CTL_MOD、EPOLL_CTL_DEL新增、修改、删除红黑树上的文件句柄。

其中epll_ctl:EPOLL_CTL_ADD新增句柄不仅仅新增红黑树节点,更关键的是对文件开始监控!

与select/poll的本质区别:并不是调用epoll_wait的时候才监听文件,而是EPOLL_CTL_ADD的时候就开始监听了。

epoll_ctl(epfd, EPOLL_CTL_ADD, fd, fdevent)核心流程:
  • 对要注册的事件event->events追加关心事件:EPOLLERR | EPOLLHUP。

​ 回忆epoll的使用中说过:EPOLLERR、EPOLLHUP事件会被自动监听,即使我们没设置。

  • 创建epitem结构,加入到红黑树中。

  • 【关键】revent = file->f_op->poll,即调用poll,把当前进程放到文件的等待队列上且设置回调函数ep_poll_callback,返回值revent是文件当前已产生事件掩码。

  • 检查返回事件:如果revent与关心事件event->events有交集(说明ADD之前事件就准备好了)。

    • 把此epitem节点拷贝到rdlist链表中;(就绪句柄拷贝到rdlist)。
    • 如果有进程在wq等待队列上(即有进程在调用epoll_wait等待),则唤醒之!
    • 顺便,如果有进程在poll_wait等待队列上(即有进程调用多路复用来监听当前epoll句柄),则唤醒之!

可以看到,如果在EPOLL_CTL_ADD一个文件之前,这个文件关心的事件就已经产生了的话,由于会唤醒wq队列上的进程,则此时EPOLL_CTL_ADD会使得epoll_wait函数从阻塞中返回。

img
再说回调函数干了什么

回调函数ep_poll_callback作为等待队列的回调函数:

当文件事件来临,唤醒文件等待队列上进程,ep_poll_callback函数将被自动调用,并把已产生事件们作为其参数传入。

回调函数ep_poll_callback核心流程:

ep_poll_callback检查已产生事件与关心事件是否有交集,如果有:

  • 将文件的epitem节点拷贝到rdlist链表上(就绪句柄拷贝到rdlist)。
  • 如果有进程在wq等待队列上(即有进程在调用epoll_wait等待),则唤醒之!
  • 顺便,如果有进程在poll_wait等待队列上(即有进程调用多路复用来监听当前epoll句柄),则唤醒之!

简而言之:回调函数把文件句柄拷贝到rdlist,并唤醒epoll_wait等待的进程。

当文件有事件来临时:
  1. 对应的等待队列上的进程被唤醒,执行回调函数ep_poll_callback,并把已产生事件们以参数传入;
  2. call ep_poll_callback;

img

简而言之:事件发生时,文件句柄被自动拷贝到rdlist,调用epoll_wait等待的进程们被唤醒。

调用epoll_wait等待事件

epoll_wait并不监听文件句柄,而是等待rdlist不空 or 收到信号 or 超时这三种条件后返回。

主要逻辑:

  1. 不断让出CPU,直到:
    • rdlist有数据;
    • 超时;
    • 收到信号;
  2. 如果rdlist有数据,则拷贝到用户传入的events数组。

img

简而言之:等待rdlist不空或者超时、信号中断,rdlist不空则把句柄们拷贝到用户空间。

拷贝到用户这个环节看边缘触发与水平触发的区别

拷贝句柄函数ep_send_events会先遍历rdlist中每个句柄,对于每个句柄,再次调用poll获取实际事件:

如果与关心事件有交集:

  • 如果句柄是水平触发(EPOLLLT),则再次把句柄加入到rdlist;否则从rdlist中删除。

于是水平模式下次还会准备好,这就是EPOLLET 与 EPOLLLT的区别原理。

  • 如果与关心事件无交集,从rdlist中删除之。

问题:如此一来看起来水平模式的句柄永远都不断重新加入rdlist,这就成永远都通知了吧?

当事件已经被处理完后,调用poll得到的实际事件与关心事件已经无交集了,于是会被删除的!

ep_send_events函数内再次调用poll获取实际事件就是为了EPOLLLT模式而生的,防止其永远加入rdlist!

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

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

相关文章

Can‘t locate IPC/Cmd.pm in @INC (@INC contains:解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

可移动磁盘上的文件删除了怎么恢复?详细教程介绍

在我们的日常生活和工作中,可移动磁盘作为一种便携式的存储设备,经常被用来备份和传输数据。然而,有时候由于误操作或不小心的删除,导致可移动磁盘上的文件丢失。这些文件可能包含重要的工作资料、个人照片、视频等,一…

【Java开发岗面试】八股文—Java虚拟机(JVM)

声明: 背景:本人为24届双非硕校招生,已经完整经历了一次秋招,拿到了三个offer。本专题旨在分享自己的一些Java开发岗面试经验(主要是校招),包括我自己总结的八股文、算法、项目介绍、HR面和面试…

【教学类-43-02】20231226 九宫格数独2.0(n=9)(ChatGPT AI对话大师生成 回溯算法)

作品展示: 背景需求: 大4班20号说:我不会做这种(九宫格),我做的是小格子的, 他把手工纸翻过来,在反面自己画了矩阵格子。向我展示: “我会做这种!” 原来他…

数据采集遇到验证码校验的一般破解方式简述

背景 百度自动采集是一种高效的数据采集方法,但是在采集过程中经常会遇到图片验证码的问题,从而导致采集失败。那么有没有什么方法可以绕过图片验证呢?本文将为您详细介绍。 解决方案 一、使用OCR技术识别验证码 OCR技术可以识别图片中的…

JS 遍历本月所有日期

代码如下: function getMonthAllDays() {// 获取当前日期var currentDate new Date(); // 获取当前月份的第一天var firstDayOfMonth new Date(currentDate.getFullYear(), currentDate.getMonth(), 1); // 获取当前月份的最后一天var lastDayOfM…

Python将普通图像转化为栅格影像

引言 本人研究的方向是遥感,研究了2年也搞没清楚普通图像和遥感影像的区别,只知道到了多了地理坐标信息,但是经纬度信息映射到每个图像像素点的底层逻辑我还不太理解。因为现在需要使用python将图像转化为栅格影像,所以在此仔细研…

超维空间S2无人机使用说明书——51、基础版——使用yolov8进行目标跟踪

引言:为了提高yolo识别的质量,提高了yolo的版本,改用yolov8进行物体识别,同时系统兼容了低版本的yolo,包括基于C的yolov3和yolov4,以及yolov7。 简介,为了提高识别速度,系统采用了G…

解决VNC连接Ubuntu服务器打开终端出现闪退情况

服务器环境 阿里云ECS服务器 操作系统:Ubuntu 20.0.4 如何使用VNC连接阿里云ECS服务器 1.阿里云官方指导:通过VNC搭建Ubuntu 18.04和20.04图形界面 2.新手入门ECS——ubuntu 20.04安装图形化界面和本地VNC连接 问题描述 使用VNC连接上新申请阿里云服…

Python 实现 PDF 到 Word 文档的高效转换(DOC、DOCX)

PDF(Portable Document Format)已成为一种广泛使用的电子文档格式。PDF的主要优势是跨平台,可以在不同设备上呈现一致的外观。然而,当我们需要对文件内容进行编辑或修改,直接编辑PDF文件会非常困难,而且效果…

分布式技术之分布式数据存储系统

文章目录 什么是分布式数据存储系统?分布式数据存储系统三要素顾客:生产和消费数据导购:确定数据位置货架:存储数据 CAP 理论指出,在分布式系统中,不能同时满足一致性、可用性和分区容错性,指导…

408计算机组成原理错题知识点拾遗

个人向错题相关部分整理,涵盖真题、模拟、课后习题等。 408相关: 408数据结构错题知识点拾遗 408数据结构常考算法基础训练等待完善 408计算机组成原理错题知识点拾遗408操作系统错题知识点拾遗等待完善408计算机网络错题知识点拾遗 408计算机网络各层协…

MYSQL的UPDATE时锁表机制

(笔记,只为获取流量券) MySQL中,UPDATE 操作涉及到行级锁和表级锁的概念,具体取决于事务隔离级别和被更新的条件, 无索引的情况下: 当表没有索引的情况下,UPDATE 操作通常会涉及到表级锁。这是…

使用Halcon 采集图像并进行简单处理rgbl_to_gray/threshold/connection/fill_up

使用Halcon 采集图像并进行简单处理 文章目录 使用Halcon 采集图像并进行简单处理 下面介绍一个简单的采集图像的例子。在Halcon中利用图像采集接口,使用USB3.0相机实时拍摄图像。采集到图像后对图像进行简单的阀值分割处理,将有物体的区域标记出来。 &a…

------- 计算机网络基础

1.1概述 是什么? 答出独立计算机通信线路连接实现资源共享 计算机网络组成 从组成部分看: 硬件软件协议 从工作方式看: 边缘部分和核心部分 从功能组成看: 通信子网和资源子网 计算机网络性能指标 速率是指数据传输的物理速度,吞吐量是指实际的数据传输…

iPhone 13 Pro 更换『移植电芯』和『超容电池』体验

文章目录 考虑换电池Ⅰ 方案一Ⅱ 方案二 总结危险 Note系列地址 简 述: 首发买的iPhone 13P &#xff08;2021.09&#xff09;&#xff0c;随性使用一年出头&#xff0c;容量就暴跌 85%&#xff0c;对比朋友一起买的同款&#xff0c;还是95%。这已经基本得一天两充 >_<&a…

【机组期末速成】指令系统|机器指令概述|操作数类型与操作类型|寻址方式|指令格式

&#x1f3a5; 个人主页&#xff1a;深鱼~&#x1f525;收录专栏&#xff1a;计算机组成原理&#x1f304;欢迎 &#x1f44d;点赞✍评论⭐收藏 目录 前言&#xff1a; 一、本章考点总览 二、考点分析 1、以下有关指令系统的说法中错误的是&#xff08; &#xff09;。 2…

使用LOTR合并检索提高RAG性能

RAG结合了两个关键元素:检索和生成。它首先使用语义搜索等高级技术来浏览大量数据&#xff0c;包括文本、图像、音频和视频。RAG的本质在于它能够检索相关信息&#xff0c;然后作为下一阶段的基础。生成组件利用大型语言模型的能力&#xff0c;解释这些数据块&#xff0c;制作连…

操作系统大题

目录 作业一&#xff1a; 前驱图 作业二&#xff1a;信号量 作业三&#xff1a;同步算法 1‘’生产者消费者问题 解1&#xff1a; 解2&#xff1a;利用AND信号量解决生产者-消费者问题 解3. 利用管程解决生产者-消费者问题 2‘’ 哲学家进餐问题&#xff08;The Dinning…

Conda:Python环境管理的瑞士军刀

在数据科学和机器学习的世界中&#xff0c;管理各种库和依赖关系的重要性不容忽视。Conda 就是为此而生的强大工具。本文将深入探讨 Conda 的简介、功能以及使用示例&#xff0c;帮助你更好地理解和使用这个工具。 Conda 简介 Conda 是一个开源的包管理系统和环境管理系统&am…