zoukankan      html  css  js  c++  java
  • bio,nio,aio

    以下是本文的目录大纲:

      一.什么是同步?什么是异步?

      二.什么是阻塞?什么是非阻塞?

      三.什么是阻塞IO?什么是非阻塞IO?

      四.什么是同步IO?什么是异步IO?

      五.五种IO模型

      六.两种高性能IO设计模式

      请尊重作者劳动成果,转载请标明原文链接:

       http://www.cnblogs.com/dolphin0520/p/3916526.html

    一.什么是同步?什么是异步?

      同步就是:如果有多个任务或者事件要发生,这些任务或者事件必须逐个地进行,一个事件或者任务的执行会导致整个流程的暂时等待,这些事件没有办法并发地执行;

      异步就是:如果有多个任务或者事件发生,这些事件可以并发地执行,一个事件或者任务的执行不会导致整个流程的暂时等待。

      因此,个人觉得同步和异步可以表现在很多方面,但是记住其关键在于多个任务和事件发生时,一个事件的发生或执行是否会导致整个流程的暂时等待

    二.什么是阻塞?什么是非阻塞?

      阻塞就是:当某个事件或者任务在执行过程中,它发出一个请求操作,但是由于该请求操作需要的条件不满足,那么就会一直在那等待,直至条件满足;

      非阻塞就是:当某个事件或者任务在执行过程中,它发出一个请求操作,如果该请求操作需要的条件不满足,会立即返回一个标志信息告知条件不满足,不会一直在那等待。

      也就是说阻塞和非阻塞的区别关键在于当发出请求一个操作时,如果条件不满足,是会一直等待还是返回一个标志信息。

    三.什么是阻塞IO?什么是非阻塞IO?

           一个完整的IO读请求操作包括两个阶段:

      1)查看数据是否就绪;

      2)进行数据拷贝(内核将数据拷贝到用户线程)。

      那么阻塞(blocking IO)和非阻塞(non-blocking IO)的区别就在于第一个阶段,如果数据没有就绪,在查看数据是否就绪的过程中是一直等待,还是直接返回一个标志信息。

    四.什么是同步IO?什么是异步IO?

           同步IO即 如果一个线程请求进行IO操作,在IO操作完成之前,该线程会被阻塞;

      而异步IO为 如果一个线程请求进行IO操作,IO操作不会导致请求线程被阻塞。

      事实上,同步IO和异步IO模型是针对用户线程和内核的交互来说的:

      对于同步IO:当用户发出IO请求操作之后,如果数据没有就绪,需要通过用户线程或者内核不断地去轮询数据是否就绪,当数据就绪时,再将数据从内核拷贝到用户线程;

      而异步IO:只有IO请求操作的发出是由用户线程来进行的,IO操作的两个阶段都是由内核自动完成,然后发送通知告知用户线程IO操作已经完成。也就是说在异步IO中,不会对用户线程产生任何阻塞。

      这是同步IO和异步IO关键区别所在,同步IO和异步IO的关键区别反映在数据拷贝阶段是由用户线程完成还是内核完成。所以说异步IO必须要有操作系统的底层支持。

      阻塞IO和非阻塞IO是反映在当用户请求IO操作时,如果数据没有就绪,是用户线程一直等待数据就绪,还是会收到一个标志信息这一点上面的。也就是说,阻塞IO和非阻塞IO是反映在IO操作的第一个阶段,在查看  数据是否就绪时是如何处理的。

    五.五种IO模型

      五种IO模型,分别是:阻塞IO、非阻塞IO、多路复用IO、信号驱动IO以及异步IO。

      下面就分别来介绍一下这5种IO模型的异同。

    1.阻塞IO模型

      最传统的一种IO模型,即在读写数据过程中会发生阻塞现象。

      当用户线程发出IO请求之后,内核会去查看数据是否就绪,如果没有就绪就会等待数据就绪,而用户线程就会处于阻塞状态,用户线程交出CPU。当数据就绪之后,内核会将数据拷贝到用户线程,并返回结果给用户线程,用户线程才解除block状态。

      典型的阻塞IO模型的例子为:

    1
    data = socket.read();

       如果数据没有就绪,就会一直阻塞在read方法。

    2.非阻塞IO模型

      当用户线程发起一个read操作后,并不需要等待,而是马上就得到了一个结果。如果结果是一个error时,它就知道数据还没有准备好,于是它可以再次发送read操作。一旦内核中的数据准备好了,并且又再次收到了用户线程的请求,那么它马上就将数据拷贝到了用户线程,然后返回。

      在非阻塞IO模型中,用户线程需要不断地询问内核数据是否就绪,也就说非阻塞IO不会交出CPU,而会一直占用CPU。

      对于非阻塞IO,在while循环中需要不断地去询问内核数据是否就绪,这样会导致CPU占用率非常高

    3.多路复用IO模型

      Java NIO实际上就是多路复用IO。

    4.异步IO模型

      异步IO模型中,IO操作的两个阶段都不会阻塞用户线程,这两个阶段都是由内核自动完成,然后发送一个信号告知用户线程操作已完成。用户线程中不需要再次调用IO函数进行具体的读写

      注意,异步IO是需要操作系统的底层支持,在Java 7中,提供了Asynchronous IO。

      无论是多路复用IO还是信号驱动模型,IO操作的第2个阶段都会引起用户线程阻塞,也就是内核进行数据拷贝的过程都会让用户线程阻塞。

    六.两种高性能IO设计模式

      一种是 多线程,一种是线程池。

      因此,为了解决这种一个线程对应一个客户端模式带来的问题,提出了采用线程池的方式,也就说创建一个固定大小的线程池,来一个客户端,就从线程池取一个空闲线程来处理,当客户端处理完读写操作之后,就交出对线程的占用。因此这样就避免为每一个客户端都要创建线程带来的资源浪费,使得线程可以重用。

      但是线程池也有它的弊端,如果连接大多是长连接,因此可能会导致在一段时间内,线程池中的线程都被占用,那么当再有用户请求连接时,由于没有可用的空闲线程来处理,就会导致客户端连接失败,从而影响用户体验。因此,线程池比较适合大量的短连接应用。

    七.NIO中的几个基础概念

         https://www.cnblogs.com/dolphin0520/p/3919162.html

      参考资料:

      《Unix网络编程》

      http://blog.csdn.net/goldensuny/article/details/30717107

      http://my.oschina.net/XYleung/blog/295122

      http://xmuzyq.iteye.com/blog/783218

      http://www.cnblogs.com/ccdev/p/3542669.html

      http://alicsd.iteye.com/blog/868702

      http://www.smithfox.com/?e=191

      http://www.cnblogs.com/Anker/p/3254269.html

      http://blog.csdn.net/hguisu/article/details/7453390

      http://www.cnblogs.com/dawen/archive/2011/05/18/2050358.html

  • 相关阅读:
    在ASP.NET WebAPI 中使用缓存【Redis】
    Redis 缓存服务配置与使用
    使用 New Relic 监控接口服务性能 (APM)
    基于OWIN WebAPI 使用OAuth授权服务【客户端模式(Client Credentials Grant)】
    svn查看代码作者的命令
    Failed to execute goal org.codehaus.mojo:rpm-maven-plugin:2.1.1:rpm (default) on project **
    Error: Cannot find a valid baseurl for repo: base
    intellij中编译报错: The packaging for this project did not assign a file to the build artifact
    fsimage 和 edits log
    查看rpm和war包内容
  • 原文地址:https://www.cnblogs.com/eryun/p/7443161.html
Copyright © 2011-2022 走看看