IO多路复用原理

  • BIO
  • NIO
  • IO多路复用之select模型和poll模型
  • IO多路复用之epoll模型
  • Reactor模型

IO多路复用技术
讲IO多路复用技术之前,我们得先了解NIO和BIO。

BIO

BIO (Block IO):同步阻塞IO。一般我们传统的JDK内置的Socket编程就是阻塞IO。其底层流程是:①创建socket接口,号为x,通过bind函数将接口号与端口号进行绑定,然后进行listn监听事件或者是read读事件,且会一直阻塞在该命令,直到有客户端连接或者发送数据。
缺点:如果是在单线程环境下,由于是阻塞地获取结果,只能有一个客户端连接。而如果是在多线程环境下,需要不断地新建线程来接收客户端,这样会浪费大量的空间。

NIO

NIO(NONBLOCK IO):同步非阻塞IO。非阻塞意味着程序无需等到结果,持续进行。其底层原理是:①同样与BIO相同创建Socket接口,号为x,绑定接口号与端口号,然后进行listen监听事件或者是读数据事件。②通过configureBlock函数传入参数false,底层命令为 fcntl(socket号,nonblock)将socket号标记为非阻塞。③循环执行。假如有客户端进行连接,则返回一个新的socket号,将新的socket号加入一个list中,然后遍历list中的元素查看有无发生read事件;如果没有客户端进行连接,则返回-1,代表没有客户端连接,再不断地循环。
缺点:需要遍历list中的每个集合查看有无监听的事件发生,时间复杂度为O(n),浪费CPU资源。

IO多路复用之select模型和poll模型

IO多路复用技术(select函数模型和poll函数模型):进程通过告诉多路复用器(内核)(也就是select函数和poll函数)所有的socket号,多路复用器再去获取每一个socket的状态,当程序获取到某个socket号有事件发生了,则去该socket号上进行处理对应的事件,read事件或者是recived事件。(补充select函数与poll函数的区别是,前者底层是数组,所以有最大连接数的限制,后者是链表,无最大连接数的限制)
缺点:①同样与NIO相同,需要遍历所有socket,O(N)复杂度。②重复传递数据。因为内核是无状态的,每次都要根据进程不断重复从用户态向内核态传递所有的socket号去遍历每一个socket,获取它们的状态。浪费资源与效率,可以使用一个记事本记录每个socket的监听事件。

IO多路复用之epoll模型

IO多路复用技术(epoll函数模型):epoll函数模型主要是调用了三个函数:epoll_create() , epoll_ctl() , epoll_wait();
底层流程:①通过epoll_create() 函数创建一个文件,返回一个文件描述符(Linus系统一切对象皆为文件)fd ② 创建socket接口号4,绑定socket号与端口号,监听事件,标记为非阻塞。通过epoll_ctl() 函数将该socket号 以及 需要监听的事件(如listen事件)写入fd中。③循环调用epoll_wait() 函数进行监听,返回已经就绪事件序列的长度(返回0则说明无状态,大于0则说明有n个事件已就绪)。例如如果有客户端进行连接,则,再调用accept()函数与4号socket进行连接,连接后返回一个新的socket号,且需要监听读事件,则再通过epoll_ctl()将新的socket号以及对应的事件(如read读事件)写入fd中,epoll_wait()进行监听。循环往复。
优点:不需要再遍历所有的socket号来获取每一个socket的状态,只需要管理活跃的连接。即监听在通过epoll_create()创建的文件中注册的socket号以及对应的事件。只有产生就绪事件,才会处理,所以操作都是有效的,为O(1).
补充:众所周知,设备(进程)是通过中断机制来请求CPU进行IO处理。使用epoll模型能加快CPU的处理效率。如网卡想通过IO来向系统传输一个数据,就通过中断获取CPU时间片,将该数据放置就绪事件序列中,等待CPU下一次进行epoll_wait()即可获取到对应数据,无需再通过往fd中注册socket号对应的事件等等。

epoll函数的边缘触发与水平触发的区别:
边缘触发:当文件描述符关联的读内核缓冲区发生变化时候,才发出可读信号进行通知
水平触发:只要文件描述符关联的读内核缓冲区非空,有数据可以读取,就一直发出可读信号进行通知
举个例子:
1.读缓冲区刚开始是空的
2.读缓冲区写入2KB数据
3.水平触发和边缘触发模式此时都会发出可读信号
4.收到信号通知后,读取了1kb的数据,读缓冲区还剩余1KB数据
5.水平触发会再次进行通知,而边缘触发不会再进行通知

因为边缘触发对于一次就绪事件只会触发一次,所以需要一次性的把缓冲区的数据读完为止,也就是一直读,直到读到缓冲区为空为止,因为这一点,边缘触发需要设置文件句柄为非阻塞。

但是,还没完,epoll模型(selector模型)还有不足,就是如果当epoll_wait()方法返回了10w个就绪事件,就需要等待这10w个就绪事件处理完成,才能继续下面的命令,去响应新的事件,这样就容易让新的事件超时。因此,提出了Reactor模型。

Reactor模型

我们可以通过更多的处理器和更多的线程来更快地处理事件。所以,提出了主从Reactor多线程模型(1个主Reactor+多个从Reactor+线程池)。

主Reactor只会进行响应客户端连接的事件,即accept事件,其余的事件交给剩下的从Reactor进行处理,进行了解耦。且由于我们的CPU一般是多核的,可以利用多线程来加快事件的处理速度。Nginx和Redis都是基于Reactor模型来实现在单线程的环境下实现与多个客户端并发交互。
Redis的IO多路复用模型

(该图片引用来自有盐先生的文章)
Netty的多路复用模型:(可以看出来是有多个Selector的,所以是基于多线程的)

IO多路复用原理(大白话,通俗易懂)相关推荐

  1. IO多路复用原理剖析

    (最近笔试遇到笔试题:select,poll,epoll都是IO多路复用的机制). I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应 ...

  2. Redis单线程还是多线程?IO多路复用原理

    目录 专栏导读 一.Redis版本迭代 二.Redis4.0之前为什么一直采用单线程? 三.Redis6.0引入多线程 四.Redis主线程和IO线程是如何完成请求的? 1.服务端和客户端建立sock ...

  3. Redis的IO多路复用原理

    什么是阻塞,非阻塞,异步同步,select,poll,epoll?今天我们用一遍文章解开这多年的迷惑. 首先我们想要通过网络接收消息,是这样的一个步骤. 用户空间向内核空间请求网络数据 内核空间把网卡 ...

  4. Socket IO多路复用: epoll原理图解

    目录 一.accept 创建新 socket 1.1 初始化 struct socket 对象 1.2 为新 socket 对象申请 file 1.3 接收连接 1.4 添加新文件到当前进程的打开文件 ...

  5. io多路复用的原理和实现_多路复用IO内幕

    什么是多路复用IO 多路复用IO (IO multiplexing) 是指内核一旦发现进程指定的一个或者多个IO条件准备读取,它就通知该进程.在Linux系统中,常用的 多路复用IO 手段有 sele ...

  6. IO多路复用底层原理及源码解析

    基本概念 1. 关于linux文件描述符 在Linux中,一切都是文件,除了文本文件.源文件.二进制文件等,一个硬件设备也可以被映射为一个虚拟的文件,称为设备文件.例如,stdin 称为标准输入文件, ...

  7. io多路复用的原理和实现_IO多路复用机制详解

    select,poll,epoll机制区别总结: 服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种: (1)同步阻塞IO(Blocking IO):即传统的IO模型. (2)同步非阻塞I ...

  8. 阻塞IO、非阻塞IO、以及多路复用原理

    阻塞IO.非阻塞IO.以及多路复用原理 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 阻塞IO.非阻塞IO.以及多路复用原理 什么是I/O 一.BIO(阻塞IO) 二.N ...

  9. io多路复用的原理和实现_彻底理解 IO 多路复用实现机制

    本文作者:何建辉(公众号:org_yijiaoqian) 点赞再看,养成习惯,微信搜一搜[一角钱技术]关注更多原创技术文章.本文 GitHub org_hejianhui/JavaStudy已收录,有 ...

最新文章

  1. JAVA安装包制作神器install4j 版本更新至v6.1.5,密码字段选项添加新属性|附下载...
  2. golang语言学习第三课 条件语句
  3. hibernate映射简单实例
  4. 【科普】一文把数据科学、人工智能与机器学习讲清楚
  5. Poj2586 每五个月都是亏
  6. lcd液晶字体_等离子电视与液晶电视的区别
  7. WeTool V6.0.0免费版多功能微信好有管理软件
  8. 对钱感兴趣?聊聊互联网工资收入的组成
  9. Git笔记(18) 搭建服务器Git
  10. mysql c接口返回自增id_详解mysql插入数据后返回自增ID的七种方法
  11. 粉笔网CEO怒斥湖南卫视扶贫节目作秀:自己赞助1000万太傻
  12. sql 24小时格式_初学SQL,80%都会踩的5个坑
  13. Oralce SQLPlus 以及shell脚本中spool输出到文件时的格式化输出
  14. vue-router配置
  15. 【转】commons-lang.jar包简介
  16. mysql unix_timestamp()获取日期的时间戳 from_unixtime时间戳转日期
  17. 你真的了解width这个属性吗
  18. Pytest的基本使用
  19. centos8安装NVIDIA显卡驱动,docker模式运行机器学习
  20. 生成网络论文阅读:PGGAN(一):论文速览

热门文章

  1. Matlab中常用机器学习函数
  2. 30岁还能转行学人工智能吗?
  3. 用通俗易懂的方式讲解Transformers
  4. 怎么给PDF去水印,一种方法就足够了
  5. 现金红包+千万流量曝光,官方帮你上热门!【 chrome插件测评2.0征稿活动开始!】
  6. 动态左侧二级下拉菜单 基于bootstrap js
  7. 廊坊职业技术学院计算机专业宿舍,廊坊职业技术学院宿舍条件怎么样
  8. Android Studio 创建对应国家语言 values
  9. 分销主机-linux站点创建,在linux中安装与使用KeyHelp虚拟主机分销面板
  10. 百度面试题,Java百度面试题