写在前面

  从事服务端开发,少不了要接触网络编程。epoll作为linux下高性能网络服务器的必备技术至关重要,nginx、redis、skynet和大部分游戏服务器都使用到这一多路复用技术。

  本文会从网卡接收数据的流程讲起,串联起CPU中断、操作系统进程调度等知识;再一步步分析阻塞接收数据、select到epoll的进化过程;最后探究epoll的实现细节。目录:

一、从网卡接收数据说起
二、如何知道接收了数据?
三、进程阻塞为什么不占用cpu资源?
四、内核接收网络数据全过程
五、同时监视多个socket的简单方法
六、epoll的设计思路
七、epoll的原理和流程
八、epoll的实现细节
九、结论

一、从网卡接收数据说起

  下图是一个典型的计算机结构图,计算机由CPU、存储器(内存)、网络接口等部件组成。了解epoll本质的第一步,要从硬件的角度看计算机怎样接收网络数据。

   下图展示了网卡接收数据的过程。在①阶段,网卡收到网线传来的数据;经过②阶段的硬件电路的传输;最终将数据写入到内存中的某个地址上(③阶段)。这个过程涉及到DMA传输、IO通路选择等硬件有关的知识,但我们只需知道:网卡会把接收到的数据写入内存。

二、如何知道接收了数据?

  了解epoll本质的第二步,要从CPU的角度来看数据接收。要理解这个问题,要先了解一个概念——中断。

  计算机执行程序时,会有优先级的需求。比如,当计算机收到断电信号时(电容可以保存少许电量,供CPU运行很短的一小段时间),它应立即去保存数据,保存数据的程序具有较高的优先级。

  一般而言,由硬件产生的信号需要cpu立马做出回应(不然数据可能就丢失),所以它的优先级很高。cpu理应中断掉正在执行的程序,去做出响应;当cpu完成对硬件的响应后,再重新执行用户程序。中断的过程如下图,和函数调用差不多。只不过函数调用是事先定好位置,而中断的位置由“信号”决定。

  以键盘为例,当用户按下键盘某个按键时,键盘会给cpu的中断引脚发出一个高电平。cpu能够捕获这个信号,然后执行键盘中断程序。下图展示了各种硬件通过中断与cpu交互。

  现在可以回答本节提出的问题了:当网卡把数据写入到内存后,网卡向cpu发出一个中断信号,操作系统便能得知有新数据到来,再通过网卡中断程序去处理数据。

三、进程阻塞为什么不占用cpu资源?

  了解epoll本质的第三步,要从操作系统进程调度的角度来看数据接收。阻塞是进程调度的关键一环,指的是进程在等待某事件(如接收到网络数据)发生之前的等待状态,recv、select和epoll都是阻塞方法。了解“进程阻塞为什么不占用cpu资源?”,也就能够了解这一步。

  为简单起见,我们从普通的recv接收开始分析,先看看下面代码:

//创建socket
int s = socket(AF_INET, SOCK_STREAM, );
//绑定
bind(s, ...)
//监听
listen(s, ...)
//接受客户端连接
int c = accept(s, ...)
//接收客户端数据
recv(c, ...);
//将数据打印出来
printf(...)

  这是一段最基础的网络编程代码,先新建socket对象,依次调用bind、listen、accept,最后调用recv接收数据。recv是个阻塞方法,当程序运行到recv时,它会一直等待,直到接收到数据才往下执行。

工作队列

  操作系统为了支持多任务,实现了进程调度的功能,会把进程分为“运行”和“等待”等几种状态。运行状态是进程获得cpu使用权,正在执行代码的状态;等待状态是阻塞状态,比如上述程序运行到recv时,程序会从运行状态变为等待状态,接收到数据后又变回运行状态。操作系统会分时执行各个运行状态的进程,由于速度很快,看上去就像是同时执行多个任务。

下图中的计算机中运行着A、B、C三个进程,其中进程A执行着上述基础网络程序,一开始,这3个进程都被操作系统的工作队列所引用,处于运行状态,会分时执行。

工作队列中有A、B和C三个进程

等待队列

当进程A执行到创建socket的语句时,操作系统会创建一个由文件系统管理的socket对象(如下图)。这个socket对象包含了发送缓冲区、接收缓冲区、等待队列等成员。等待队列是个非常重要的结构,它指向所有需要等待该socket事件的进程。

当程序执行到recv时,操作系统会将进程A从工作队列移动到该socket的等待队列中(如下图)。由于工作队列只剩下了进程B和C,依据进程调度,cpu会轮流执行这两个进程的程序,不会执行进程A的程序。所以进程A被阻塞,不会往下执行代码,也不会占用cpu资源。

ps:操作系统添加等待队列只是添加了对这个“等待中”进程的引用,以便在接收到数据时获取进程对象、将其唤醒,而非直接将进程管理纳入自己之下。上图为了方便说明,直接将进程挂到等待队列之下。

唤醒进程

当socket接收到数据后,操作系统将该socket等待队列上的进程重新放回到工作队列,该进程变成运行状态,继续执行代码。也由于socket的接收缓冲区已经有了数据,recv可以返回接收到的数据。

IO模型(epoll)--详解-01的更多相关文章

  1. (转)Linux下select, poll和epoll IO模型的详解

    Linux下select, poll和epoll IO模型的详解 原文:http://blog.csdn.net/tianmohust/article/details/6677985 一).Epoll ...

  2. Linux下select, poll和epoll IO模型的详解

    http://blog.csdn.net/tianmohust/article/details/6677985 一).Epoll 介绍 Epoll 可是当前在 Linux 下开发大规模并发网络程序的热 ...

  3. I/O模型之二:Linux IO模式及 select、poll、epoll详解

    目录: <I/O模型之一:Unix的五种I/O模型> <I/O模型之二:Linux IO模式及 select.poll.epoll详解> <I/O模型之三:两种高性能 I ...

  4. (转载) Linux IO模式及 select、poll、epoll详解

    注:本文是对众多博客的学习和总结,可能存在理解错误.请带着怀疑的眼光,同时如果有错误希望能指出. 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案 ...

  5. (转)Linux IO模式及 select、poll、epoll详解

    本文为转载,并作了部门调整.修改. [原文出处:https://segmentfault.com/a/1190000003063859] 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么 ...

  6. Linux IO模式及 select、poll、epoll详解(转)

    同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案是不同的.所以先限定一下本文的上下文. 本文讨论的背景是Linux环境下的network IO. ...

  7. 网络通信 --> IO多路复用之select、poll、epoll详解

    IO多路复用之select.poll.epoll详解      目前支持I/O多路复用的系统调用有 select,pselect,poll,epoll,I/O多路复用就是通过一种机制,一个进程可以监视 ...

  8. Linux IO模式以及select poll epoll详解

    一 背景 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案是不同的.所以先限定一下本文的上下文. 本文讨论的背景是Linux环境下的network ...

  9. 高并发网络编程之epoll详解(转载)

    高并发网络编程之epoll详解(转载) 转载自:https://blog.csdn.net/shenya1314/article/details/73691088 在linux 没有实现epoll事件 ...

  10. Linux下的I/O复用与epoll详解(转载)

    Linux下的I/O复用与epoll详解 转载自:https://www.cnblogs.com/lojunren/p/3856290.html  前言 I/O多路复用有很多种实现.在linux上,2 ...

随机推荐

  1. Linux 部署 Django 系统

    一:安装uwsgi pip3 install uwsgi 二:进入项目目录下,创建uwsgi.ini配置文件 [uwsgi] # 使用nginx连接时使用功能,上线时才使用socket,指定项目执行的 ...

  2. ELK 日志平台构建

    elastic中文社区 https://elasticsearch.cn/ 完整参考 ELK实时日志分析平台环境部署--完整记录 https://www.cnblogs.com/kevingrace/ ...

  3. 爱伪装(AWZ)/爱立思(ALS)改机改串一键新机原理分析

    简介 爱伪装(AWZ)/爱立思(ALS)是一款iOS越狱系统上的改机工具,可以修改多种系统参数达到伪装设备型号及各种软硬件属性的目的,同时提供了防越狱检测机制,常用于iOS上的推广刷量,配合代理/VP ...

  4. ORACLE 左连接 右连接 内连接 外连接 全连接 五中表连接方式

    1.左连接 :left join 2.右连接:right join 3.内连接:inner join 4.外连接:outer join 5.全连接:full join

  5. 【VS开发】【DSP开发】浅谈Linux PCI设备驱动(一)

    要弄清楚Linux PCI设备驱动,首先要明白,所谓的Linux PCI设备驱动实际包括Linux PCI设备驱动和设备本身驱动两部分.不知道读者理不理解这句话,本人觉得这句话很重要,对于PCI.US ...

  6. 【VS开发】设备控制台 (DevCon.exe) 命令

    设备控制台 (DevCon.exe) 命令 DevCon (DevCon.exe) 是一个命令行工具,可以显示有关运行 Windows 的计算机上设备的详细信息.还可以使用 DevCon 启用.禁用. ...

  7. 中间消息件之 Solace(一) Solace的简介

    什么是Solace? Solace是一家加拿大注册的公司,总部设在安大略省渥太华. 成立于2001年. 这家公司一直致力于获取信息的艺术和科学,并提供世界上最灵活,最强大的数据移动平台. 背景 在信息 ...

  8. java 实现读取某个目录下指定类型的文件

    我这里是读取txt类型的文件,在指定的目录下有不同类型的文件 实现代码,读取txt类型的文件并打印出该文件的绝对路径 package com.SBgong.test; import java.io.F ...

  9. python学习笔记四 (运算符重载和命名空间、类)

    从以上代码中应该了解到: obj.attribute  查找的顺序: 从对象,类组成的树中,从下到上,从左到右到查找最近到attribute属性值,因为rec中存在name的属性,所以x.name可以 ...

  10. p1000 A+B问题

    题目描述 Description 输入两个整数A和B,输出他们的和 输入描述 Input Description 输入为一行,包含两个整数A,B.数据保证A与B都在2^31-1的范围内 输出描述 Ou ...