IO、NIO、IO多路复用

这篇具有很好参考价值的文章主要介绍了IO、NIO、IO多路复用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

IO是什么?

IO分为两类,它们之间是有区别的,而且有很大的区别;

1. 文件系统的IO
也叫本地io,就是和磁盘或者外围存储设备进行读写操作,外围设备有USB、移动硬盘等等;

2. 网络的IO
将数据发送给对方 和 读取对方的数据就称为网络IO;

网络IO是如何连接的?

网络IO就是本机的应用程序对着内核的缓冲区读写的过程,发送数据时应用程序会将数据复制到内核态的写队列中,再由内核将数据复制到网卡,然后进行发送;读取数据则反过来,网卡接受到数据后将数据复制到内核态的读队列中,在通知应用程序来获取数据;

IO、NIO、IO多路复用,nio,php,开发语言

下面是一次网络读取内容的I/O示意图,数据先从外设(网卡)到内核空间,再到用户空间(JVM),最后到应用程序的一个过程。

上述一次I/O读取,所谓的阻塞和非阻塞体现在哪里呢?

Java最早期的版本的I/O就是这样实现的。当程序调用到读取I/O的时候,同步阻塞住程序,直到数据从网卡写入内核空间,在写入用户空间才返回数据,程序才可以继续进行。

BIO
BIO为同步阻塞IO,blocking queue的简写,也就是说多线程情况下只有一个线程操作内核的queue,当前线程操作完queue后,才能给下一个线程操作;
IO、NIO、IO多路复用,nio,php,开发语言
如图1所示,用户线程通过系统调用read发起IO读操作,由用户空间转到内核空间。内核等到数据包到达后,然后将接收的数据拷贝到用户空间,完成read操作。

用户线程使用同步阻塞IO模型的伪代码描述为:

{

read(socket, buffer);

process(buffer);

}

即用户需要等待read将socket中的数据读取到buffer后,才继续处理接收的数据。整个IO请求的过程中,用户线程是被阻塞的,这导致用户在发起IO请求时,不能做任何事情,对CPU的资源利用率不够。

在BIO下,一个连接就对应一个线程,如果连接特别多的情况下,就会有特别多的线程,很费线程;在早期的时候,世界上的计算机还很少,网站也少,会上网的人更是寥寥无几,并发最高的时候也就几十上百个,所以当并发量不高的情况下,BIO也够用了;

NIO (流程图)
Non-blocking IO的简写,同步非阻塞IO,内核发生了变化,app访问内核的缓冲区时不会阻塞,但是返回值需要用户自己判断;如果连接数特别多的i情况下,就需要应用程序不停遍历,一个个进行状态的判断,询问是否有数据到达;
IO、NIO、IO多路复用,nio,php,开发语言
如图2所示,由于socket是非阻塞的方式,因此用户线程发起IO请求时立即返回。但并未读取到任何数据,用户线程需要不断地发起IO请求,直到数据到达后,才真正读取到数据,继续执行。

用户线程使用同步非阻塞IO模型的伪代码描述为:

{
    while(read(socket, buffer) != SUCCESS);
    process(buffer);
}

即用户需要不断地调用read,尝试读取socket中的数据,直到读取成功后,才继续处理接收的数据。整个IO请求的过程中,虽然用户线程每次发起IO请求后可以立即返回,但是为了等到数据,仍需要不断地轮询、重复请求,消耗了大量的CPU的资源。一般很少直接使用这种模型,而是在其他IO模型中使用非阻塞IO这一特性。

IO 多路复用

多路是指网络连接,复用指的是同一个线程

为什么有IO多路复用机制?

没有IO多路复用机制时,有BIO、NIO两种实现方式,但有一些问题

IO多路复用模型是建立在内核提供的多路分离函数select基础之上的,使用select函数可以避免同步非阻塞IO模型中轮询等待的问题。

IO、NIO、IO多路复用,nio,php,开发语言
如图3所示,用户首先将需要进行IO操作的socket添加到select中,然后阻塞等待select系统调用返回。当数据到达时,socket被激活,select函数返回。用户线程正式发起read请求,读取数据并继续执行。

从流程上来看,使用select函数进行IO请求和同步阻塞模型没有太大的区别,甚至还多了添加监视socket,以及调用select函数的额外操作,效率更差。但是,使用select以后最大的优势是用户可以在一个线程内同时处理多个socket的IO请求。用户可以注册多个socket,然后不断地调用select读取被激活的socket,即可达到在同一个线程内同时处理多个IO请求的目的。而在同步阻塞模型中,必须通过多线程的方式才能达到这个目的。

用户线程使用select函数的伪代码描述为:

{

select(socket);

while(1) {

sockets = select();

for(socket in sockets) {

if(can_read(socket)) {

read(socket, buffer);

process(buffer);

}

}

}

}

其中while循环前将socket添加到select监视中,然后在while内一直调用select获取被激活的socket,一旦socket可读,便调用read函数将socket中的数据读取出来。

然而,使用select函数的优点并不仅限于此。虽然上述方式允许单线程内处理多个IO请求,但是每个IO请求的过程还是阻塞的(在select函数上阻塞),平均时间甚至比同步阻塞IO模型还要长。如果用户线程只注册自己感兴趣的socket或者IO请求,然后去做自己的事情,等到数据到来时再进行处理,则可以提高CPU的利用率。文章来源地址https://www.toymoban.com/news/detail-806835.html

到了这里,关于IO、NIO、IO多路复用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • BIO到NIO、多路复用器, 从理论到实践, 结合实际案例对比各自效率与特点(下)

    本篇文章是BIO到NIO、多路复用器, 从理论到实践, 结合实际案例对比各自效率与特点(上)的下一篇, 如果没有看的小伙伴, 可以先看下, 不然可能会不连贯. 多路复用器是对于传统NIO的优化, 解决了传统NIO无法直接获取所有所有连接的状态, 需要挨个遍历所有连接查看是否准备就绪

    2024年02月10日
    浏览(34)
  • 驱动开发,IO多路复用实现过程,epoll方式

    被称为当前时代最好用的io多路复用方式; 核心操作:一棵树(红黑树)、一张表(内核链表)以及三个接口;  思想:(fd代表文件描述符)         epoll要把检测的事件fd挂载到内核空间红黑树上,遍历红黑树,调用每个fd对应的操作方法,找到发生事件的fd,如果没有发

    2024年02月07日
    浏览(41)
  • NIO 非阻塞式IO

    Java NIO 基本介绍 Java NIO 全称 Java non-blocking IO ,是指 JDK 提供的新 API 。从 JDK1.4 开始, Java 提供了一系列改进的输入/输出的新特性,被统称为 NIO (即 NewIO ),是同步非阻塞的。 NIO 相关类都被放在 java.nio 包及子包下,并且对原 java.io 包中的很多类进行改写。 NIO 有三大核心

    2024年02月13日
    浏览(28)
  • java-IO&NIO

    1.1. 阻塞 IO 模型   最传统的一种 IO 模型,即在读写数据过程中会发生阻塞现象。当用户线程发出 IO 请求之后,内 核会去查看数据是否就绪,如果没有就绪就会等待数据就绪,而用户线程就会处于阻塞状态,用户线程交出 CPU。当数据就绪之后,内核会将数据拷贝到用户线程

    2024年02月12日
    浏览(30)
  • Java 中的 IO 和 NIO

    Java IO(Input/Output)流是用于处理输入和输出数据的机制。它提供了一种标准化的方式来读取和写入数据,可以与文件、网络、标准输入输出等进行交互。 Java IO流主要分为两个流模型:字节流(Byte Stream)和字符流(Character Stream)。 字节流(Byte Stream) InputStream:字节输入流

    2024年02月10日
    浏览(30)
  • IO多路复用详解

    在IO多路复用模型中,引入了一种新的系统调用,查询IO的就绪状态。在Linux系统中,对应的系统调用为select/poll/epoll系统调用。通过该系统调用,一个进程可以监视多个文件描述符,一旦某个描述符就绪(一般是内核缓冲区可读/可写),内核能够将就绪的状态返回给应用程序

    2024年02月08日
    浏览(39)
  • 说说IO多路复用

    IO多路复用 I/O multiplexing 这里面的 multiplexing 指的其实是在单个线程通过记录跟踪每一个Sock(I/O流)的状态(对应空管塔里面的Fight progress strip槽)来同时管理多个I/O流。直白点说:多路指的是多个socket连接,复用指的是复用一个线程进行管理。发明它的原因,是尽量多的提高服务

    2024年02月09日
    浏览(27)
  • IO多路复用练习

    一、通过select搭建TCP服务器 二、通过select搭建TCP客户端 三、通过poll搭建客户端

    2024年02月12日
    浏览(25)
  • 网络模型与 IO 多路复用

      socket也称作“套接字”,用于描述IP地址和端口,是一个通信链路的描述符。应用程序通常通过“套接字”向对端发出请求或者应答网络请求。   socket是连接运行在网络上的两个程序之间的通信端点。通信的两端都有socket,它是一个通道,数据在两个socket之间进行传输

    2024年02月01日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包