阻塞IO和非阻塞IO的区别
转载地址:
http://blog.sina.com.cn/s/blog_a46817ff0101g0gv.html
http://blog.csdn.net/nodeathphoenix/article/details/30389317
有很多人把阻塞认为是同步,把非阻塞认为是异步;个人认为这样是不准确的,当然从思想上可以这样类比,但方式是完全不同的,下面说说在JAVA里面阻塞IO和非阻塞IO的区别
在JDK1.4中引入了一个NIO的类库,使得Java涉及IO的操作拥有阻塞式和非阻塞式两种,问一下阻塞IO与非阻塞IO有什么区别?有什么优缺点?
在阻塞模式下,若从网络流中读取不到指定大小的数据量,阻塞IO就在那里阻塞着。比如,已知后面会有10个字节的数据发过来,但是我现在只收到8个字节,那么当前线程就在那傻傻地等到下一个字节的到来,对,就在那等着,啥事也不做,直到把这10个字节读取完,这才将阻塞放开通行。
在非阻塞模式下,若从网络流中读取不到指定大小的数据量,非阻塞IO就立即通行。比如,已知后面会有10个字节的数据发过来,但是我现在只收到8个字节,那么当前线程就读取这8个字节的数据,读完后就立即返回,等另外两个字节再来的时候再去读取。
从上面可以看出,阻塞IO在性能方面是很低下的,如果要使用阻塞IO完成一个Web服务器的话,那么对于每一个请求都必须启用一个线程进行处理。而使用非阻塞IO的话,一到两个线程基本上就够了,因为线程不会产生阻塞,好比一下接收A请求的数据,另一下接收B请求的数据,等等,就是不停地东奔西跑,直接到把数据接收完了。
虽然说,非阻塞IO比阻塞IO有更高的性能,但是对于开发来的,难度就成数倍递增了。由于是有多少数据就读取多少数据,这样在读取完整之前需要将已经读取到的数据保存起来,而且需要与其他地方来的数据隔离开来不能混在一起,否则就不知道这数据是谁的了
区别:
读:
读本质来说其实不能是读,在实际中, 具体的接收数据不是由这些调用来进行,是由于系统底层自动完成的。read也好,recv也好只负责把数据从底层缓冲copy到我们指定的位置。
在阻塞条件下,如果没有发现数据在网络缓冲中会一直等待,当发现有数据的时候会把数据读到用户指定的缓冲区。但是如果这个时候读到的数据量比较少,比参数中指定的长度要小,read并不会一直等待下去,而是立刻返回。read的原则是数据在不超过指定的长度的时候有多少读多少,没有数据就会一直等待。所以一般情况下我们读取数据都需要采用循环读的方式读取数据,一次read完毕不能保证读到我们需要长度的数据,read完一次需要判断读到的数据长度再决定是否还需要再次读取。
  在非阻塞的情况下,read的行为是如果发现没有数据就直接返回,如果发现有数据那么也是采用有多少读多少的进行处理.对于读而言,阻塞和非阻塞的区别在于没有数据到达的时候是否立刻返回。
recv中有一个MSG_WAITALL的参数 recv(sockfd, buff, buff_size, MSG_WAITALL)。在正常情况下 recv是会等待直到读取到buff_size长度的数据,但是这里的WAITALL也只是尽量读全,在有中断的情况下recv还是可能会被打断,造成没有读完指定的buff_size的长度。所以即使是采用recv + WAITALL参数还是要考虑是否需要循环读取的问题,在实验中对于多数情况下recv还是可以读完buff_size,所以相应的性能会比直接read进行循环读要好一些。不过要注意的是这个时候的sockfd必须是处于阻塞模式下,否则WAITALL不能起作用。
写:
写的本质也不是进行发送操作,而是把用户态的数据copy到系统底层去,然后再由系统进行发送操作,返回成功只表示数据已经copy到底层缓冲,而不表示数据以及发出,更不能表示对端已经接收到数据。
  在阻塞的情况,是会一直等待直到write完全部的数据再返回。这点行为上与读操作有所不同,究其原因主要是读数据的时候,通常刚开始我们并不知道要读的数据的长度,而是在数据的头部设置了一个长度,在读完指定长度的头部后,才知道整个要读的数据长度。如果一开始就贸然设置一个要读的数据长度,然后像阻塞的write那样去等读完,则很可能会造成死循环;而对于write,由于需要写的长度是已知的,所以可以一直再写,直到写完.不过问题是write是可能被打断造成write一次只write一部分数据,所以write的过程还是需要考虑循环write, 只不过多数情况下一次write调用就可能成功。
  
非阻塞写的情况,是采用可以写多少就写多少的策略。与读不一样的地方在于,有多少读多少是由网络发送端是否有数据传输到本地内核缓存为准。但是对于可以写多少是由本地的网络堵塞情况为标准的,在网络阻塞严重的时候,网络层没有足够的内存来进行写操作,这时候就会出现写不成功的情况,阻塞情况下会尽可能(有可能被中断)等待到数据全部发送完毕, 对于非阻塞的情况就是一次写多少算多少,没有中断的情况下也还是会出现write到一部分的情况。
阻塞IO和非阻塞IO的区别的更多相关文章
- 简述同步IO、异步IO、阻塞IO、非阻塞IO之间的联系与区别
		
POSIX 同步IO.异步IO.阻塞IO.非阻塞IO,这几个词常见于各种各样的与网络相关的文章之中,往往不同上下文中它们的意思是不一样的,以致于我在很长一段时间对此感到困惑,所以想写一篇文章整理一下. ...
 - 同步IO、异步IO、阻塞IO、非阻塞IO之间的联系与区别
		
POSIX 同步IO.异步IO.阻塞IO.非阻塞IO,这几个词常见于各种各样的与网络相关的文章之中,往往不同上下文中它们的意思是不一样的,以致于我在很长一段时间对此感到困惑,所以想写一篇文章整理一下. ...
 - 阻塞IO、非阻塞IO的区别
		
1.类与类之间的关系:依赖,实现,泛化(继承),关联,组合,聚合. 1)依赖(虚线):一个类是 另一个类的函数参数 或者 函数返回值. 2)实现(实线加小圆):对纯虚函数类(抽象类)的实现. 3)继承 ...
 - 阻塞IO,非阻塞IO,异步IO和非异步IO 的区别
		
最近在研究java IO.NIO.NIO2(或者称AIO)相关的东西,有些概念还是要明确下. 按照<Unix网络编程>的划分,IO模型可以分为:阻塞IO.非阻塞IO.IO复用.信号驱动IO ...
 - 网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO
		
同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问题其实不同的人给出 ...
 - 转 网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO
		
此文章为转载,如有侵权,请联系本人.转载出处,http://blog.chinaunix.net/uid-28458801-id-4464639.html 同步(synchronous) IO和异步( ...
 - 阻塞式和非阻塞式IO
		
有很多人把阻塞认为是同步,把非阻塞认为是异步:个人认为这样是不准确的,当然从思想上可以这样类比,但方式是完全不同的,下面说说在JAVA里面阻塞IO和非阻塞IO的区别 在JDK1.4中引入了一个NIO的 ...
 - 理论铺垫:阻塞IO、非阻塞IO、IO多路复用/事件驱动IO(单线程高并发原理)、异步IO
		
完全来自:http://www.cnblogs.com/alex3714/articles/5876749.html 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同 ...
 - Python_阻塞IO、非阻塞IO、IO多路复用
		
0.承上 进程: 计算机里最小的资源分配单位: 数据隔离, 利用多核,数据不安全. 线程: 计算机中最小的CPU调度单位: 数据共享,GIL锁,数据不安全. 协程: 线程的一部分,是有用户来调度的; ...
 
随机推荐
- Ubuntu18.04安装OpenCV4.1.0
			
Ubuntu18.04安装OpenCV4.1.0 1.首先要安装依赖 sudo apt-get install build-essential \ cmake git libgtk2.0-dev pk ...
 - mysql中的分区
			
第18章:分区 目录 18.1. MySQL中的分区概述 18.2. 分区类型 18.2.1. RANGE分区 18.2.2. LIST分区 18.2.3. HASH分区 18.2.4. KEY分区 ...
 - 9种Java单例模式详解(推荐)
			
单例模式的特点 一个类只允许产生一个实例化对象. 单例类构造方法私有化,不允许外部创建对象. 单例类向外提供静态方法,调用方法返回内部创建的实例化对象. 懒汉式(线程不安全) 其主要表现在单例类在外 ...
 - 如何避免重复安装AppiumSetting、Unlock以及Android ime
			
老版本Appium(如1.4.16),找到如下路径(根据自己的安装路径找) C:\Program Files (x86)\Appium\node_modules\appium\lib\devices\ ...
 - percona-toolkit主从同步整理(MySQL)
			
前言:MYSQL主从同步架构是目前使用最多的数据库架构之一,尤其是负载比较大的网站,因此对于主从同步的管理也就显得非常重要.而数据作为软件的核心部分,对于其有效的管理显得更为重要.随着时间的推移,软件 ...
 - 通过LVM备份mysql数据库脚本
			
#!/bin/bash #******************************************************************** #encoding -*-utf8- ...
 - IAR astyle代码美化
			
Menu Text填写上我们期望的名字,我们可以填入格式化代码,command内填入AStyle的地址, Argument内填入参数: --style=ansi -s4 -S -Y -D -xe ...
 - Beyond Compare 4 使用30天后过期续用方法
			
Beyond Compare 4 使用30天后过期续用方法 windows上的Beyond Compare 4软件过期了,两个方法: 方案一: 找到Beyond Compare 4安装目录,安装时默认 ...
 - c++ 用eclipse建立一个类,并实例化并运行
			
新建项目 file->new->c/c++ project 项目结构 cpc.cpp //================================================= ...
 - TypeError: Object of type 'ListSerializer' is not JSON serializable
			
问题: 解决:ser.data是json数据,你想要的