IO操作:同步,异步,阻塞,非阻塞

来源:互联网 发布:数字摇号软件 编辑:程序博客网 时间:2024/05/16 17:51

思考:

编程讨论的I/O模型,一般是在网络通信方面

对I/O模型的理解抓住一个关键点,I/O操作分两步:

1、等待数据准备好

2、将数据从内核空间拷贝到用户空间

a) 阻塞和非阻塞I/O,一般讨论的是第一阶段,等待数据准备好的策略。阻塞I/O的意思是,一直等待数据准备好,才进行到下一步;非阻塞I/O,查看数据是否准备好,如果在规定时间内还没准备好,那么就返回错误,如果数据准备好了,就进行下一步。

b) 此外还有信号驱动式I/O,此方式一旦调用就立刻返回,如果数据就绪,内核会发送一个信号给调用进程,然后进程执行到下一步。信号驱动式I/O和后面将要提到的异步I/O有相似的地方,区别是:信号驱动式I/O,内核发送信号告诉进程,什么时候启动IO操作,I/O操作本身还是阻塞的;异步I/O是,内核发送信号告诉进程数据读取什么时候完成,不会出现I/O阻塞的情况。

c) I/O多路复用:虽然I/O多路复用的函数也是阻塞的,但是其与以上两种还是有不同的,I/O多路复用是阻塞在select,epoll这样的系统调用之上,而没有阻塞在真正的I/O系统调用如recvfrom之上。也就是,I/O多路复用在等待数据准备好这一阶段,针对单个I/O口并不会阻塞,但是将数据从内核空间拷贝到用户空间依旧会阻塞进程。

d) 异步I/O:调用异步I/O系统立刻返回,等到 等待数据准备好,将数据从内核空间拷贝到用户空间这两步操作都完成,内核才向进程发送信号。也就是整个操作(包括等待数据准备好,从内核拷贝数据均不在调用进程里面执行)

总结:

同步I/O和异步I/O区别在第二步:同步I/O在将数据从内核拷贝到用户空间时,会出现阻塞;而异步I/O,在将数据从内核拷贝到用户空间时不是调用进程完成,因此不会阻塞进程。

阻塞I/O,非阻塞I/O、信号驱动I/O、I/O多路复用,都属于同步I/O。


同步 :调用进程自己处理I/O读写

异步 :使用异步I/O时,将I/O读写委托给内核处理


Java对BIO、NIO、AIO的支持:

BIO 同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。

NIO 同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。

AIO 异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理,

BIO、NIO、AIO适用场景分析:

BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。

NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。

AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。


既然网络上众说纷纭,不如找个权威参考一下,这个权威就是《UNIX网络编程:卷一》第六章——I/O复用。书中向我们提及了5种类UNIX下可用的I/O模型:

  • 阻塞式I/O;

  • 非阻塞式I/O;

  • I/O复用(select,poll,epoll...);

  • 信号驱动式I/O(SIGIO);

  • 异步I/O(POSIX的aio_系列函数);

阻塞式I/O模型:默认情况下,所有套接字都是阻塞的。怎么理解?先理解这么个流程,一个输入操作通常包括两个不同阶段:

(1)等待数据准备好;
(2)从内核向进程复制数据。


对于一个套接字上的输入操作,第一步通常涉及等待数据从网络中到达。当所有等待分组到达时,它被复制到内核中的某个缓冲区。第二步就是把数据从内核缓冲区复制到应用程序缓冲区。 好,下面我们以阻塞套接字的recvfrom的的调用图来说明阻塞

202707564.jpg

标红的这部分过程就是阻塞,直到阻塞结束recvfrom才能返回。

非阻塞式I/O: 以下这句话很重要:进程把一个套接字设置成非阻塞是在通知内核,当所请求的I/O操作非得把本进程投入睡眠才能完成时,不要把进程投入睡眠,而是返回一个错误。看看非阻塞的套接字的recvfrom操作如何进行

202858660.jpg

可以看出recvfrom总是立即返回。

I/O多路复用:虽然I/O多路复用的函数也是阻塞的,但是其与以上两种还是有不同的,I/O多路复用是阻塞在select,epoll这样的系统调用之上,而没有阻塞在真正的I/O系统调用如recvfrom之上。如图

202009980.jpg

信号驱动式I/O:用的很少,就不做讲解了。直接上图

202028686.jpg

异步I/O:这类函数的工作机制是告知内核启动某个操作,并让内核在整个操作(包括将数据从内核拷贝到用户空间)完成后通知我们。如图:

202055894.jpg

注意红线标记处说明在调用时就可以立马返回,等函数操作完成会通知我们。

等等,大家一定要问了,同步这个概念你怎么没涉及啊?别急,您先看总结。 其实前四种I/O模型都是同步I/O操作,他们的区别在于第一阶段,而他们的第二阶段是一样的:在数据从内核复制到应用缓冲区期间(用户空间),进程阻塞于recvfrom调用。相反,异步I/O模型在这两个阶段都要处理。

wKiom1LLqEPC2DSMAAUHeILYGZ4097.jpg

再看POSIX对这两个术语的定义:

  • 同步I/O操作:导致请求进程阻塞,直到I/O操作完成;

  • 异步I/O操作:不导致请求进程阻塞。

好,下面我用我的语言来总结一下阻塞,非阻塞,同步,异步

  • 阻塞,非阻塞:进程/线程要访问的数据是否就绪,进程/线程是否需要等待;

  • 同步,异步:访问数据的方式,同步需要主动读写数据,在读写数据的过程中还是会阻塞;异步只需要I/O操作完成的通知,并不主动读写数据,由操作系统内核完成数据的读写。

  • 转载自:http://yaocoder.blog.51cto.com/2668309/1308899

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 排卵期有什么症状腰痛 排卵期计算法周期表 女人的排卵期怎么算 排卵期排出褐色分泌物 女生排卵期有什么反应 排卵期出血的症状和图片 排卵期症状有哪些症状 排卵期是不是容易怀孕 一个月排卵期有几天 排卵期肚子痛怎么回事 排卵期体温会升高吗 排卵期测体温怎么测 排卵期肚子疼是在排卵吗 排卵期腰痛是怎么回事 排卵期没有射会怀孕吗 女人排卵期计算方法 排卵期有什么症状白带 排卵期是什么时候有什么反应 女孩排卵期是什么时候 排卵期不带套子外射会怀孕吗 排卵期怎么算计算器 女的排卵期是什么时候 女生排卵期有什么特征 排卵期一定会怀孕吗 排卵期小肚子疼是怎么回事 排卵期身体有什么症状 女人的排卵期怎么算才准确 女性排卵期有什么症状 什么是排卵期怎么计算 排卵期第几天容易怀孕 排卵期是什么时候到什么时候 排卵期有什么症状或感觉 排卵期体重会增加吗 排卵期受完孕有什么感觉 排卵期出血可以运动吗 排卵期为什么没怀上 排卵期出血一般几天 排卵期几次可以怀孕 排卵期出血什么症状 排卵期出血什么原因 排卵期一般什么时候