IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 面试部分难点梳理 - IO多路复用 -> 正文阅读

[网络协议]面试部分难点梳理 - IO多路复用

IO多路复用

  • 如果用JUC的方式来类比理解一下,BIO是相当于整个APP都加了synchronied,NIO相当于是使用自旋的方式。
    在这里插入图片描述

Linux操作系统中断

中断的分类

  • 内中断:陷入(系统调用),故障(缺页中断),终止(程序BUG)
  • 外中断: I/O中断请求(设备准备就绪),人工干预(Ctrl + C);
    在这里插入图片描述

系统中断,内核做什么事情

内核态 - 执行系统调用

Socket

Socket基础

在这里插入图片描述

在这里插入图片描述

Socket读写缓冲区机制

用户态和内核态

  • Socket在底层采用TCP/IP协议,因此在数据传输的过程中是可以保证可靠性的。
  • APP处于用户态,是无法处理TCP/IP协议的,必须要将其所需要传输的数据通过系统调用,传输到操作系统的内核空间中。
  • 当操作系统处于内核态时,可以通过底层的方法,建立Socket连接,来传输数据。

缓冲区

  • APP在用户空间中也有缓冲区,操作系统在内核空间中也有缓冲区。
  • 内核空间的缓冲区是用来接收/发送TCP/IP传输过程中的数据缓冲。
  • 用户空间的缓冲区是用来读取/写入内核缓冲区中的数据。
  • 内核缓冲区中分成了输入缓冲区,和输出缓冲区。

BIO

  • 如果一个APP写入输入缓冲区时,会对输出缓冲区加锁,同一时间仅仅能有该APP执行输入输出操作,如果输出缓冲区不足,也会加锁,该APP等待数据传输完成,再写入。其他APP必须等待该APP完成才能将自己的数据写入缓冲区。
  • app
    在这里插入图片描述

NIO

  • 如果缓冲区有剩余,则APP中的数据写入缓冲区,如果没写完,则返回写到的数据位置。
    在这里插入图片描述
  • 如果缓冲区没有剩余,或者正在进行TCP/IP的数据传输,则返回-1,表示该次写入失败。
    在这里插入图片描述

BIO

  • 将内核的数据缓冲区写到APP的用户数据缓冲区,如果没写完就会阻塞,直到所有需要的数据都写入了缓冲区才结束。
    在这里插入图片描述

NIO

  • NIO不会堵塞,采用轮询的方式,持续查询缓冲区中是否有数据,有数据就直接写入用户缓冲区中,没有就直接返回。

内核缓冲区满的情况

BIO

  • TCP会不断尝试去写,上层APP也会被挂起,直到等到缓冲区有位置可以写,APP会写入数据到内核缓冲区。
    在这里插入图片描述

NIO

  • NIO会不断尝试去写,如果缓冲区数据满了就会返回-1,表示此次写失败。

系统调用,用户态<—>内核态

为什么要有这两种状态

  • 有些功能是仅仅操作系统才能使用,例如系统调用。
  • 同时用户态有用户堆栈,内核态下有内核堆栈。

什么时候会切换到内核态

  • 当发生中断的时候会切换到内核态
  • 内中断:陷入(系统调用:例如申请外部I/O资源),故障(缺页中断),终止(系统bug)
  • 外中断:外部I/O设备准备就绪,强行干预(Ctrl + C)

状态切换时,要做什么事情

  • 保护用户堆栈的寄存器的现场。
  • 同时执行内核堆栈的程序。
  • 在中断执行之后,会重现现场,继续执行用户堆栈的程序。
    在这里插入图片描述

具体流程

  1. 用户态
    1. 查找自己需要调用哪一个系统资源。
    2. 将用户参数变量保存到操作系统的寄存器内。
    3. 保存进程的上下文信息
    4. 切换到进程内核栈
    5. 根据映射表调用System_call函数
  2. 内核态
    1. 取到指定的寄存器的号码。
    2. 从寄存器中取出参数变量。
    3. 将需要的数据从用户态拷贝到内核态
    4. 执行函数
    5. 将结果从内核空间拷贝到寄存器中
  3. 用户态
    1. 回复现场
    2. 读取寄存器中的数值到用户空间中
    3. 继续程序
      在这里插入图片描述

BIO通信底层原理

  • 刘老师的原理图
  • 我认为BIO就是一个线程仅仅关注自己的那个端口号,如果自己想要接收信息的客户端没有发送过来信息,就阻塞挂起,直到有信息发过来,被唤醒,获取数据。
  • 而NIO就是一个线程一次性关注多个端口号,通过一定的手段识别那个端口号的数据对应哪个服务器的端口,再将对应端口号的数据发布出去。

select多路复用

  • 刘老师的流程图
  • 在Linux中,我们可以使用select函数实现I/O端口的复用,传递给select函数的参数会告诉内核:
    在这里插入图片描述
    1. 我们所关心的文件描述符((读)readset、(写)writeset、(异常)exceptset )
    2. 对每个描述符,我们所关心的状态。
      (对于内核态的接收到位图来说,0表示没有对应端口需要操作,1表示有对应端口需要操作)。
      (对于用户态的接收位图来说,0表示对应缓冲区没有数据,1表示对应缓冲区有数据)。
    3. 我们要等待多长时间。(timeout)
  • 从select函数返回后,内核告诉我们一下信息:
    1. 对我们的要求已经做好准备的描述符的个数
    2. 对于三种条件哪些描述符已经做好准备.(读,写,异常)
      有了这些返回信息,我们可以调用合适的I/O函数(通常是read或write),并且这些函数不会再阻塞.
      在这里插入图片描述
  • maxfdp:bitmap表示的最大有效位,指定从0到n的位图标识位是有效的。
    在这里插入图片描述
  • select()问题:
    1. 内核态和用户态之间需要频繁的拷贝fd_set
    2. 重新置位(因为用户态的rset 和 内核态的rset 是不一样的,每次进行select 都会导致rset 不同 因此不能复用)
    3. fd_set位图的数目是有限制的,最大是1024
    4. 都要从索引0开始遍历 有很多位置都是0 会浪费时间。

epoll多路复用

epoll_create()

在这里插入图片描述

  • 这个函数表示开启size个epoll结构空间,返回epoll文件描述符编号。
  • 直接创建到内核空间的epoll中。

epoll_ctl()对epoll监听列表中的epoll进行修改

  • 在这里插入图片描述
  • 在这里插入图片描述
  • epfd: epoll结构的进程fd编号,函数将依靠该编号找到对应的epol结构。
  • op:表示当前请求类型,增加、减少、修改epoll结构中的结构,由三个宏定义(EPOLL_CTL_ ADD:注册新的fd到epfd中)、(EPOLL_CTL_MOD:修改已经注册的fd的监听事件)、(EPOLL_CTL_DEL:从epfd中删除一个fd)
  • fd,需要监听的文件描述符,需要监听的端口号,一般指socket _fd,
  • event,告诉内核对该fd资源感兴趣的事件(输入,输出等)
  • 在这里插入图片描述

epoll_wait()对epoll就绪队列进行修改

  • 在这里插入图片描述
  • 在这里插入图片描述
  • epfd: epoll结构的进程fd编号,目前线程感兴趣的epoll编号。
  • *events, 是一个指针,必须指向一个epoll_event结构数组, 当函数返回时,内核会把就绪状态的数据拷贝到该数组中!
  • maxevent,标明参数二epoll_event数组最多能接收的数据量,即本次操作最多能获取多少就绪数据。
  • timeout,为0则表示立刻返回不阻塞,为+n则表示阻塞n秒,为-1则表示一直阻塞,直到接收到数据。

epoll相对select的优点

  • epoll的大小可以很大,不被1024限制。
  • 用户直接在内核空间中注册epoll空间
  • epoll_wait中的都是已经操作过的epoll,无用的epoll不会进入epoll_wait中,也不会被返回。select中用0来表示没有被操作,这样节省了遍历的时间。
  • epoll_wait返回的是接收数据的epoll数目;nfds
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-03-24 00:56:55  更:2022-03-24 00:58:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 6:01:27-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码