精华内容
下载资源
问答
  • 当缓冲区有数据时,堵塞IO与非堵塞IO都是能读多少数据就读多少数据读完立即返回,返回值读取到的字节数。当缓冲区空时,对于堵塞IO堵塞住,CPU会切换给其他进程或者线程;对于非堵塞IO,read函数会返回-1并且...

    堵塞IO与非堵塞IO的区别

    1、对于read操作。当缓冲区有数据时,堵塞IO与非堵塞IO都是能读多少数据就读多少数据读完立即返回,返回值为读取到的字节数。当缓冲区为空时,对于堵塞IO会堵塞住,CPU会切换给其他进程或者线程;对于非堵塞IO,read函数会返回-1并且设置错误码为EAGIAN或者EWOULDBLOCK。
    2、对于write操作。当缓冲区足够容纳要写入数据时,堵塞与非堵塞IO都会把全部数据都写入缓冲区后立即返回,返回值为写入的大小。当缓冲区不足时,对于堵塞IO,write操作会堵塞住,CPU切换给其他进程或者线程,直到全部数据都写入为止,函数返回写入的大小,但是如果对端发送了RST报文关闭连接或者超时等错误,那么write函数立即返回,返回写入的数据大小,如果再次调用write函数,会返回-1,更新错误码;对于非堵塞IO,write函数会写入能写入的数据,返回写入的大小,如果缓冲区不能写入任何数据,则返回-1并且更新错误码为EAGAIN或者EWOLDBLOCK。
    3、对于监听套接字。当已连接队列有连接的socket时,堵塞与非堵塞IO调用accept函数都会返回已连接的socket。当已连接队列为空时,对于堵塞IO会堵塞在accept函数,直到有新的连接建立,CPU切换给其他进程或者线程;对于非堵塞IO,accept函数会返回-1并且更新错误码为EAGAIN或者EWOLDBLOCK。
    4、对于客户端的connect。对于堵塞IO会堵塞在connect函数的调用上,直到三次握手完成连接建立成功,connect返回0;对于非堵塞IO,connect函数会立即返回-1更新错误码为EINPROGRESS,linux内核会继续完成三次握手,应用程序可以用select,poll,epoll的IO复用技术获取连接成功事件。

    为什么Linux的IO多路复用技术需要用非堵塞IO

    场景一:客户端设置如下的选项:

    struct linger ling;
    ling.l_onoff = 1; 
    ling.l_linger = 0;
    setsockopt(socket_fd, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling));
    close(socket_fd);
    

    当客户端连接建立成功的时候,立即调用close函数(或者连接建立后可能core了),那么此时客户端会发送RST报文关闭连接;当服务端收到连接后,poll等IO复用技术检测到连接事件,但是服务端可能会过一会会才调用accept函数,在调用accept的时间间隔内,由于连接已经关闭了,linux会把连接从已连接队列删除。如果是堵塞IO,那么应用程序将堵塞在accept函数上面。
    场景二:select检测到可写后,应用程序就可以调用write函数,往缓冲区里面写数据,但是缓冲区可能不足以存放要写的数据,那么非堵塞IO将堵塞在write函数上面。
    故Linux的IO多路复用技术需要用非堵塞IO。

    展开全文
  • 为什么IO模式非常重要?由于现代的计算机和操作系统的架构决定了CPU是稀缺资源,大家都要来一起竞争。而IO(特别是网络相关的IO)的速度往往较慢。所以怎样进行IO就有了多种模式,包含同步、异步、堵塞、非堵塞等等...

    为什么IO模式非常重要?由于现代的计算机和操作系统的架构决定了CPU是稀缺资源,大家都要来一起竞争。而IO(特别是网络相关的IO)的速度往往较慢。所以怎样进行IO就有了多种模式,包含同步、异步、堵塞、非堵塞等等。


    不少人把这几个概念放到一起讨论,非常多时候也难以区分。


    这里从根上剖析下该怎么看待这几个概念。


    首先。异步和同步是相对的,而同步情况下又有堵塞和非堵塞之分。


    异步非常easy理解。当用户程序须要进行IO的时候,发出IO请求,然后就立马返回。能够继续做其他事情。

    比如。从网络收包,当包抵达后放到内核某个缓存区,而且从内核空间放置到程序须要的用户空间后(一种是直接复制。比較费资源;一种是映射mmap),通知程序,程序之后就能够处理数据了。

    这是最理想的模式。CPU干活效率最高。


    同步情况则是,当用户程序须要进行IO的时候,发出IO请求。然后就等着数据到达后进行处理(首先将数据从内核空间拷贝到用户空间,然后进行操作)。

    详细怎么等呢?一种就是堵塞在那里。CPU就处理其他的程序去了;一种就是发现没有数据就返回一个错误,程序能够干点别的事情(一般是不断轮询)。过会还得自动回来看看数据OK了么。


    同步情况下显然效率比較差,于是有了各种技术来改进它,一种就是IO多路复用(用一个专门的线程来负责IO)。包含Linux上的select、poll和epoll。

    select和poll类似,都是用一个内核优化线程来不断轮询IO,一旦有数据了用户程序就能够利用系统调用将数据从内核空间拷贝到用户空间。之后进行处理。这尽管提高了效率,但事实上仍然是一种同步模式。

    epoll则更进一步。採用了底层的notify机制和mmap,底层数据可用后通知IO线程,并利用mmap将数据直接映射到用户空间。

    此时用户程序能够直接对数据进行操作了。

    展开全文
  • NIO堵塞

    2021-06-07 20:24:11
    NIO全称: No Blocking IO,是非阻塞型IO BIO全称:Blocking IO,是阻塞型IO 阻塞IO的弊端 在等待的过程中,什么事也做不了 非阻塞IO的好处 不需要一直等待,当一切就绪了再去做 NIO和BIO的区别 区别一 BIO是堵塞...

    NIO概述

    • NIO和BIO
      NIO全称为: No Blocking IO,是非阻塞型IO
      BIO全称为:Blocking IO,是阻塞型IO
    • 阻塞IO的弊端
      在等待的过程中,什么事也做不了
    • 非阻塞IO的好处
      不需要一直等待,当一切就绪了再去做

    NIO和BIO的区别

    • 区别一
      BIO是堵塞的,NIO是非堵塞的
    • 区别二
      BIO是面向流的,NIO是面向缓冲区的
      BIO中数据传输是单向的,NIO中的缓冲区是双向的

    NIO的三大模板

    1. 缓冲区 :用来存储数据
    2. 通道 :用来建立连接和传输数据
    3. 选择器:监视通道的状态

    NIO创建缓冲区对象

    方法名 说明
    static ByteBuffer allocate(长度) 创键byte类型的缓冲区
    static ByteBuffer wrap(byte[] array) 创键一个有内容的byte类型缓冲区

    NIO缓冲区添加数据

    在这里插入图片描述

    public static void main(String[] args) {
            /**
             *        int position()		  当前要操作的索引
             *        int limit() 		  最多能操作到哪个索引
             *        int capacity()		  缓冲区的总长度
             *        remaining()
             *        hasRemaining()
             */
            //创建一个缓冲区长度为50
            ByteBuffer byteBuffer = ByteBuffer.allocate(50);
            System.out.println(byteBuffer.position());//0
            System.out.println(byteBuffer.limit());//10
            System.out.println(byteBuffer.capacity());//10
    
    
            //put(byte b)一次添加一个字节,也可以添加一个字节数组
            byteBuffer.put((byte) 97);
            byteBuffer.put("aaa".getBytes());
    
    
            /*
              读写位置:表示当前进行读写操作时的位置,初始化为0,即缓冲区开始读或者写数据的位置。可以通过调用ByteBuffer对象的positon(int)方法设置它的值,通过position()可以获取它的值
              position(int newPosition) 修改position
             */
            System.out.println("当前要操作的元素"+byteBuffer.position());
            byteBuffer.position(1);
    
    
            //读写限制:最多能操作到哪个元素,也就是缓冲区可以利用范围的最大值,可以调用ByteBuffer对象的limit(int)方法进行设置,调用ByteBuffer对象的limit()获取缓冲区读写限制的大小;在刚开始创建缓冲区的时候limit的大小等于capacity。
            System.out.println("最多能操作到哪个索引"+byteBuffer.limit ());
            
            
            // 即容量,也就是缓冲区的大小。它的值是在创建缓冲区的时候指定的,设定后无法对其进行修改
            System.out.println("缓冲区的总长度"+byteBuffer.capacity ());
    
            byteBuffer.put("0123456789".getBytes());
            //ByteBuffer.remaining(),此方法最给力,返回剩余的可用长度,此长度为实际读取的数据长度
            System.out.println(byteBuffer.remaining());
            
            
            //hasRemaining()方法用于判断当前位置和限制之间是否有任何元素。
            System.out.println(byteBuffer.hasRemaining());
        }
    

    NIO缓冲区读取数据

    方法名 介绍
    flip() 切换读写模式
    get() 读一个字节
    get(byte[] arr) 读多个字节
    get(int index) 读指定索引的字节
    rewind() 将position设置为0,可以重复读
    clean() 数据读写完毕,再次写数据之前,需要调用clear方法
    array() 将缓冲区数据转换为字节数组返回
     public static void main(String[] args) {
            ByteBuffer byteBuffer = ByteBuffer.allocate(10);
            byteBuffer.put("abc".getBytes());
    
            //flip()  切换读写模式(写读)
            byteBuffer.flip();
            //get()   读一个字节
            while(byteBuffer.limit() != byteBuffer.position()){
                System.out.println((char) byteBuffer.get());
            }
             public static void main(String[] args) {
            ByteBuffer byteBuffer = ByteBuffer.allocate(10);
            byteBuffer.put("abc".getBytes());
    
            //flip()  切换读写模式(写读)
            byteBuffer.flip();
            //get()   读一个字节
            while(byteBuffer.limit() != byteBuffer.position()){
                System.out.println((char) byteBuffer.get());
            }
    
            System.out.println ("---------------------");
            //rewind() 将position重置为0,可以重复读
            byteBuffer.rewind();
            for (int i = 0; i < byteBuffer.limit(); i++) {
                System.out.println((char) byteBuffer.get());
            }
            System.out.println ("---------------------");
    
            //clear()     数据读写完毕(读->写)
            byteBuffer.clear();
            byteBuffer.put("qqq".getBytes());
    
            //array()     将缓冲区转换成字节数组
            byte[] bytes = byteBuffer.array();
            System.out.println(new String(bytes));
        }
    
            //clear()     数据读写完毕(读->写)
            byteBuffer.clear();
            byteBuffer.put("qqq".getBytes());
    
            //array()     将缓冲区转换成字节数组
            byte[] bytes = byteBuffer.array();
            System.out.println(new String(bytes));
        }
    
    展开全文
  • NIO与IO

    2011-08-10 12:23:36
    大家都知道NIO可以提高IO效率, 但为什么NIO可以提高IO效率,以及NIO的非堵塞技术是如果实现的,相信还有很多人不甚了解,下面是我学习时找的内容,晒出来和大家分享。  原来的I/O库与NIO最重要的区别是数据打包...
    大家都知道NIO可以提高IO效率, 但为什么NIO可以提高IO效率,以及NIO的非堵塞技术是如果实现的,相信还有很多人不甚了解,下面是我学习时找的内容,晒出来和大家分享。 

    原来的I/O库与NIO最重要的区别是数据打包和传输的方式的不同,原来的 I/O 以流 的方式处理数据,而 NIO 以块 的方式处理数据。 
       面向流的I/O系统一次一个字节地处理数据。一个输入流产生一个字节的数据,一个输出流消费一个字节的数据。为流式数据创建过滤器非常容易。链接几个过滤器,以便每个过滤器只负责单个复杂处理机制的一部分,这样也是相对简单的。不利的一面是,面向流的I/O通常相当慢。 
    http://zhangshixi.iteye.com/blog/679959 

    Java NIO非堵塞技术实际是采取Reactor模式,或者说是Observer模式为我们监察I/O端口,如果有内容进来,会自动通知我们,这样,我们就不必开启多个线程死等,从外界看,实现了流畅的I/O读写,不堵塞了。 
    http://www.lifevv.com/tenyo/doc/20070831141139791.html 


    nio的主要作用就是用来解决速度差异的。举个例子:计算机处理的速度,和用户按键盘的速度。这两者的速度相差悬殊。如果按照经典的方法:一个用户设定一个线程,专门等待用户的输入,无形中就造成了严重的资源浪费:每一个线程都需要珍贵的cpu时间片,由于速度差异造成了在这个交互线程中的cpu都用来等待。 
    nio套接字是怎么做到的? 
    其实,其中的思想很简单:轮询。一个线程轮询多个input;传统的方式是:有n个客户端就要有n个服务线程+一个监听线程,现在采取这种凡是,可以仅仅使用1个线程来代替n个服务线程以此来解决。 
    具体应用例子: 
    http://aga.iteye.com/blog/206691
    展开全文
  • 有人觉得堵塞就是同步,非堵塞就是异步,其实以前我也是这么想的,其实同步与堵塞这完全是两码事,所以写篇文章来说说为什么是两码事,也顺便说说各种组合的可以达到的效果,帮助大家了解底层的原理. 首先需要了解这些...
  • 但是,为什么CPU密集型的要用多进程呢?不是进程占用的资源很多,进程切换就占用很多CPU资源,这样合理吗? Neo Ko 无 12 人赞同了该回答 Python,特指CPython的实现,由于GIL的存在,CPython不能有效的利用多核...
  • 1.采用内存存储数据,相比磁盘存储快很多 2.非堵塞io多路复用。 多路:多个网络连接 复用:公用一个线程 3.单线程操作,避免了不必要的上下文切换和竞争条件 ...
  • Netty是一个高性能 事件驱动、异步非堵塞IO(NIO)Java开源框架,Jboss提供,用于建立TCP等底层的连接,基于Netty可以建立高性能的Http服务器,快速开发高性能、高可靠性的网络服务器和客户端程序。支持HTTP、 ...
  • NIO 靠什么解决C10K

    2020-12-24 09:16:07
    堵塞IO 之所以需要给每个socket长连接,指定一个线程 就是因为它堵塞嘛 现在这个NIO API 它具备非堵塞特性了,就可以用一个线程去检查N个socket NIO包给我们提供了一个选择器selector 然后我们需要把检查的socket...
  • Netty介绍为什么要使用non-blocking IO(NIO)堵塞IO(blocking IO)和非堵塞IO(non-blocking IO)对照Java NIO的问题和在Netty中的解决方式 Netty是基于Java NIO的网络应用框架,假设你是Java网络方面的新手,那么本章...
  • 面试题整理(下)

    2019-06-07 19:07:07
    1 nio是什么?原理是什么?解决什么问题?如何实现?...2.IO/NIO的区别,为什么要用NIO,使用IO中的Buffered..也能实现NIO的面向缓冲,什么情况下用NIO? io面向流/nio面向缓冲的 io是阻塞的/n...
  • nginx介绍及特点

    千次阅读 2019-06-28 13:37:47
    # 为什么选择nginx 1. 采用io多路复用的epoll模型,一种io空闲主动上报机制(内核态fd就绪被放入使用),一个线程并行处理io请求,没有堵塞。不会因为某一路请求的io堵塞导致后面在请求无法执行。 sel...
  • java面试题杂记

    2021-05-31 12:30:30
    java面试题杂记 图片均借鉴 1BIO、NIO、AIO 有什么区别...AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO ,异步 IO 的操作基于事件和回调机制。 2接口和抽象类有什么区别? 实现:抽象类的.
  • node 基本原理

    2018-04-16 15:43:00
    SSR 服务端渲染,为什么做服务端渲染呢,提高SEO,还有就是减少http请求,首屏加载慢的问题 node如何部署和nginx怎么连接,安全性怎么样 vue+node 1. 异步IO原理浅析 a. 异步IO的好处 前端通过异步IO可以消除UI...
  • 同步和阻塞

    2017-03-04 00:39:46
    有人觉得堵塞就是同步,非堵塞就是异步,其实以前我也是这么想的,其实同步与堵塞这完全是两码事,所以写篇文章来说说为什么是两码事,也顺便说说各种组合的可以达到的效果,帮助大家了解底层的原理.  首先需要了解...
  • Java nio初步了解

    2016-03-13 21:58:32
    但是由于bio是堵塞io,所以也有人称之Non-block io。叫什么都无所谓啦,开心就好。 NIO简介概念:缓冲BufferBuffer是一个对象,它包含了一些要写入或要读出的数据。在nio类库加入buffer对象,体现了新库与原I/O...
  • 基于NIO的三种Reactor模式

    千次阅读 2019-04-13 18:00:51
    传统的bio堵塞类型io传输由于每一次进行数据传输的时候都需要等待排队,因此效率低下,后期随着jdk的一步步发展,nio非堵塞技术开始变多越来越加广泛。 什么是Reactor Reactor可以理解反应器模式。当一个...
  • netty学习记录

    2018-06-27 10:41:00
    是一个高性能 事件驱动、异步非堵塞io开源框架; 基于NIO的客户端,服务器端编程框架; 稳定性和伸缩性; (BIO(Blocking I/O)同步阻塞I/O、NIO (New I/O) 同步非阻塞I/O、AIO (Asynchronous I/O) 异步非...
  • 官网 https://sentinelguard.io/ 服务雪崩 微服务中各个服务之间通过http/rpc互相调用,假设其中1个服务因为网络或自身原因出现问题,调用这个服务就会出现线程堵塞,此时若有大量请求出现,...Sentinel 以流量切入点
  • 前面几个章节基本上把和netty相关的知识点都介绍了一遍,零碎的知识都学会了,就需要总结一下,为什么netty的性能如此之高?有哪些思想是可以给开发者借鉴的? 记下来就概括一下: 异步非堵塞通信:Netty的IO线程...
  • 文章目录what is dstat基本用法直接跟数字,表示#秒收集一次数据,默认一秒;dstat 5表示5秒更新一次 在Linux中监控系统各项性能的工具简直不要...vmstat可以监控进程、内存、内存分页、堵塞IO、traps和CPU活动。...
  • 面试总结第二篇

    2020-06-01 15:59:54
    6.treemap的数据结构,为什么能进行排序 7.mysql的数据,inndb索引数据结构 8.主键索引和唯一索引的区别 9.springboot扫描机制 10.Java锁 syn和 tranlock 区别 11.redis数据结构 12.mybatis一级缓存二级缓存 13.堵塞io...
  • ThinkInJava

    2013-05-28 14:36:27
    7.6.9 为什么要用内部类:控制框架 7.7 构建器和多形性 7.7.1 构建器的调用顺序 7.7.2 继承和finalize() 7.7.3 构建器内部的多形性方法的行为 7.8 通过继承进行设计 7.8.1 纯继承与扩展 7.8.2 下溯造型与运行期类型...
  • Java初学者入门教学

    2012-03-14 21:17:15
    7.6.9 为什么要用内部类:控制框架 7.7 构建器和多形性 7.7.1 构建器的调用顺序 7.7.2 继承和finalize() 7.7.3 构建器内部的多形性方法的行为 7.8 通过继承进行设计 7.8.1 纯继承与扩展 7.8.2 下溯造型与运行期类型...

空空如也

空空如也

1 2 3
收藏数 42
精华内容 16
关键字:

io为什么堵塞