对epoll机制的学习理解v1

epoll机制

wrk用非阻塞多路复用IO技术创造出大量的连接,从而达到很好的压力测试效果。epoll就是实现IO多路复用的关键。

本节是对epoll的本质的学习总结,进一步的参考资料为: 《深入理解Nginx:模块开发与架构解析(第二版)》,陶辉

首先分析网络数据接收模型。

计算机分为硬件中断和软件中断,硬件中断是由外接设备产生的,比如网卡,键盘,鼠标等这些都是硬件设备。硬件设备向CPU发出中断信号,高电平信号到达CPU引脚,触发CPU立即执行中断。软中断就是由程序产生的中断。

当网卡收到外部网络发送过来的数据,网卡会做相应的处理,然后网卡发送数据到计算机内存中,之后向CPU发出硬件中断信号。CPU得到信号后立即中断当前任务,去处理网络数据,将内存中的网络数据写入socket对象中,同时唤醒等待该数据的进程。 socket对象用于收发网络数据,socket对象由进程创建后被文件描述符指向,即fd指针。socket对象指定了"端口号”,而网络数据包里包含了端口号,这使得CPU可以准确将数据写入对应的socket中。socket对象里有三个数据结构: 发送缓冲区,接收缓冲区和等待队列。接收缓冲区就是负责接收内存中的数据,并且等待被进程处理。等待队列实际上是指针,该指针指向进程时,表示进程处于等待状态,于是CPU不会处理该进程,而是处理其他进程,直到该进程被中断程序唤醒,同时中断程序移除被监听的socket上的等待队列,这样该进程重新加入进程的运行状态,被CPU处理,这样,进程拿到了socket缓冲区中的数据,recv这一环顺利通过,可以执行下一步。

在早期,互联网用户少,因此一台服务器每当被一个客户端连接,就建立一个进程,该进程只监听一个socket, 服务器能够承受住负载。当用户越来越多时,一台服务器仍然起大量进程已不现实。因此一个进程监听多个连接的技术应运而生,这就是IO多路复用技术。

最早的IO多路复用技术的思路较为简单,这就是select方法。

进程创建并监听多个socket对象,这些socket对象的描述符被写到数组fds中,进程执行系统调用select时,操作系统将进程放入每个socket的等待队列,此时进程被阻塞。其中任意一个socket被写入数据(实际上,唤醒工作是中断程序做的),进程就会被唤醒,并遍历fds中的socket对象,并读取缓冲数据,从而继续执行下去,此时进程处于运行态。 select方法让一个进程等待再唤醒执行它的过程中,一共有3次遍历,2次内核传递。让进程处于等待状态时,等待即阻塞,因为CPU执行其他进程去了,所以等待状态下的进程不消耗CPU资源,该进程会被操作系统放入被监听的所有的socket的等待队列中,因此需要遍历fds,遍历之前需要把fds整个列表传递到内核去。等到设备接收到网络数据,进程被唤醒的时候,操作系统要将fds中每个socket的等待队列中的进程指针清空,因此再一次遍历,遍历前仍然要传递fds到内核。涉及到进程的操作必然由内核执行,进程内部的执行则是用户空间权限,不需要内存干涉。最后一次遍历,是进程遍历fds上的socket(fds本来就在用户态),直到找到有缓冲数据的。

这样会带来两个问题,1.频繁的内核传递,2.频繁的遍历。问题的根源在于,进程的每一次状态更新就要重新传递fds以及遍历(fds的状态更新)。传递fds的原因显而易见,每一次调用select都是一次独立的监听一群socket的行为,在实际场景下,fds中的socket并不会较大规模地变化,因此fds最好整个列表只传一次,如果有修改,也只是对整个小增小减。遍历既源于fds传递至内核后要让fds中的每个socket和进程建立联系,也源于进程唤醒后要寻找到有缓冲数据的socket, 所以最好能进程和fds一次建立联系,然后进程能一次就找到需要的socket. fds的状态变化和进程状态的变化是一起发生的,能不能让它们分开发生?即进程的状态变化不需要和fds重新建立连接?此外,进程也不知道fds哪个socket发生了变化,因为fds不存储发生变化的信息。进程既然要和fds每个socket发生关系,为什么fds不派一个管理者代表来和进程沟通呢?这个管理者,就是event poll。 epoll就是在fds的基础上,增加了一个eventpoll数据结构,进程创建fds之后,其中的socket都为空时(如果不为空,recv直接拿到socket数据,就不阻塞了),进入阻塞状态,此时fds列表整体传入内核。所有socket与eventpoll对象建立关系,即将eventpoll对象放入所有socket的等待列表里。然后eventpoll对象的等待列表中放入进程。这是epoll方法下的进程阻塞模型,eventpoll不会频繁地改变状态,所以fds列表只传一次。eventpoll还维护一个rdlist数组,当多个socket收到数据,内核中断程序拿到了网络数据包中的五元组信息,拿到了端口号,找到了socket对象,同时知道了socket对象的地址,于是在rdlist数组中写入这些socket对象的地址。进程被唤醒时,被从eventpoll的等待列表里移除,进程又读取rdlist中的socket对象地址,直接找到收到数据的socket. epoll的核心在于操作eventpoll管理进程状态改变,只要传递一次fds,遍历1次fds就可以阻塞进程,唤醒进程则只需操作一次eventpoll。极大降低了开销。epoll的根本原理还是中间层原理。 参考

注1:等待队列的真正意思是,该socket有个列表,里面存储了所有监听该socket的进程的fd描述符。所以,可以有多个进程监听同一个端口。

注2:网卡将数据写入内存,中断程序将内存中的数据写入socket对象中。 唤起进程的是中断程序,中断程序是硬中断发起后,被CPU执行的。唤起进程的同时,将所有等待队列清空,清空后便可以CPU执行该进程,执行中,遍历socket,如果哪个socket收到了数据,便处理哪一个recv. select,就是选择,就是遍历式地选择。

注3:进程是被内核管理的,所以,操作进程,就必须将所涉及到的数据传递给内核。内核和应用空间的关系,理解成包围和被包围的关系更为合适。 其他小问题 什么是事件?

事件是被进程所等待的数据。1个事件可以让多个进程等待。 为什么说等待了,就会阻塞呢?

因为进程A创建完socket之后,下一步到了recv方法,此时进程A被丢入(其实是生成一个等待中的引用)socket对象的等待队列中去(内存),CPU就去执行其他的进程了。直到有socket事件被硬中断传入,CPU将其写入内存,进程A才再次被唤醒。 为什么阻塞是进程调度关键的一环?

阻塞又叫做等待状态,等待什么? 进程在等待某一个事件的发生,在等待时,无法进入下一步状态。对于处理网络的进程,就是等待接收网络数据包。 eventpoll对象的数据结构是怎样的? eventpoll用到了红黑树。就绪列表需要快速地被加入和删除,所以,就绪列表是红黑树。 为什么select监视的最大socket数量是1024个?

因为select在每次进程状态改变时候,要3次遍历fds列表,2次将fds列表传递到内核,fds列表变大,即提升了遍历时间,又因为复制更大的数据传递至内核,用户空间到内核空间的复制传输开销较大。所以限制了fds的大小。默认最大是1024.

原文创作:goto2091

原文链接:https://www.cnblogs.com/goto2091/p/15430763.html

更多推荐

更多
  • AWS自动化机器学习-十一、MLSDLC 的持续集成、部署和训练 技术要求,编纂持续集成阶段,管理持续部署阶段,管理持续训练,延伸,构建集成工件,构建测试工件,构建生产工件,自动化持续集成流程,回顾构建阶段,回顾测试阶段,审查部署和维护阶段,回顾应用用户体验,创建新的鲍鱼调查数据,回顾持续训练流程,清
    Apache CN

  • AWS自动化机器学习-六、使用 AWS 步骤函数自动化机器学习过程 技术要求,介绍 AWS 步骤功能,使用 Step 函数 Data Science SDK for CI/CD,建立 CI/CD 渠道资源,创建状态机,解决状态机的复杂性,更新开发环境,创建管道工件库,构建管道应用构件,部署 CI/CD
    Apache CN

  • AWS自动化机器学习-第三部分:优化以源代码为中心的自动化机器学习方法 本节将向您介绍整体 CI/CD 流程的局限性,以及如何将 ML 从业者的角色进一步整合到管道构建流程中。本节还将介绍这种角色集成如何简化自动化过程,并通过向您介绍 AWS Step 函数向您展示一种优化的方法。本节包括以下章节:
    Apache CN

  • AWS自动化机器学习-一、AWS 上的自动化机器学习入门 技术要求,洗钱流程概述,洗钱过程的复杂性,端到端 ML 流程示例,AWS 如何使 ML 开发和部署过程更容易自动化,介绍 ACME 渔业物流,ML 的情况,从数据中获得洞察力,建立正确的模型,训练模型,评估训练好的模型,探索可能的后续步
    Apache CN

  • AWS自动化机器学习-二、使用 SageMaker 自动驾驶器自动化机器学习模型开发 技术要求,介绍 AWS AI 和 ML 前景,SageMaker 自动驾驶器概述,利用 SageMaker 自动驾驶器克服自动化挑战,使用 SageMaker SDK 自动化 ML 实验,SageMaker Studio 入门,准备实验
    Apache CN

  • AWS自动化机器学习-四、机器学习的持续集成和持续交(CI/CD) 四、机器学习的持续集成和持续交CI/CD技术要求,介绍 CI/CD 方法,通过 CI/CD 实现 ML 自动化,在 AWS 上创建 CI/CD 管道,介绍 CI/CD 的 CI 部分,介绍 CI/CD 的 CD 部分,结束循环,采取以部
    Apache CN

  • AWS自动化机器学习-九、使用 Amazon Managed Workflows 为 Apache AirFlow 构建 ML 工作流 技术要求,开发以数据为中心的工作流程,创建合成鲍鱼调查数据,执行以数据为中心的工作流程,构建和单元测试数据 ETL 工件,构建气流 DAG,清理, 在前面的年龄计算器示例中,我们了解了如何通过 ML 从业者和开发人员团队之间的跨职能
    Apache CN

  • AWS自动化机器学习-七、使用 AWS 步骤函数构建 ML 工作流 技术要求,构建状态机工作流,执行集成测试,监控管道进度,设置服务权限,创建 ML 工作流程, 在本章中,我们将从第六章中的 [处继续,使用 AWS 步骤函数自动化机器学习过程。您将从那一章中回忆起,我们正在努力实现的主要目标是简化
    Apache CN

  • AWS自动化机器学习-八、使用 Apache Airflow 实现机器学习过程的自动化 技术要求,介绍阿帕奇气流,介绍亚马逊 MWAA,利用气流处理鲍鱼数据集,配置 MWAA 系统的先决条件,配置 MWAA 环境, 当建立一个 ML 模型时,有一个所有 ML 从业者都知道的基本原则;也就是说,最大似然模型只有在数据被训练时
    Apache CN

  • AWS自动化机器学习-五、自动化 ML 模型的持续部署 技术要求,部署 CI/CD 管道,构建 ML 模型工件,执行自动化 ML 模型部署,整理管道结构,创建 CDK 应用,部署管道应用,查看建模文件,审查申请文件,查看模型服务文件,查看容器构建文件,提交 ML 工件,清理, 在 [第 4
    Apache CN

  • 近期文章

    更多
    文章目录

      推荐作者

      更多