`
jzhihui
  • 浏览: 266077 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

I/O模型:阻塞、非阻塞 & 同步、异步

阅读更多

 

这篇文章主要总结下这几个概念,前几天看到微博里在讨论,当时也有点搞不清楚,昨天在看到Reactor和Proactor模式的时候,又提到相关概念,索性搞搞清楚,写个总结。

 

《Unix网络编程卷1:套接字联网API》(下面称为卷1)第6章对Unix I/O模型有5种划分:阻塞式I/O模型,非阻塞式I/O模型,I/O复用模型,信号驱动式I/O,异步I/O模型。这里我们只关心跟我们主题相关的四类:

阻塞式I/O模型:应用进程调用I/O操作时阻塞,只有等待要操作的数据准备好,并复制到应用进程的缓冲区中才返回。

非阻塞式I/O模型:当应用进程要调用的I/O操作会导致该进程进入阻塞状态时,该I/O调用返回一个错误,一般情况下,应用进程需要利用轮询的方式来检测某个操作是否就绪。数据就绪后,实际的I/O操作会等待数据复制到应用进程的缓冲区中以后才返回。

I/O复用模型:阻塞发生在select/poll的系统调用上,而不是阻塞在实际的I/O系统调用上。select/poll发现有数据就绪后,通过实际的I/O操作将数据复制到应用进程的缓冲区中。

异步I/O模型:应用进程通知内核开始一个异步I/O操作,并让内核在整个操作(包含将数据从内核复制到应该进程的缓冲区)完成后通知应用进程。

 

对于上面的分类,卷1给出了一个很形象的图,如下:

 

从上面图中可以看出,卷1中把I/O操作分为两个阶段,第一阶段等待数据可用,第二阶段将数据从内核复制到用户空间。前三种模型的区别在于第一阶段(阻塞式I/O阻塞在I/O操作上,非阻塞式I/O轮询,I/O复用阻塞在select/poll或者epoll上),第二阶段都是一样的,即这里的阻塞不阻塞体现在第一阶段,从这方面来说I/O复用类型也可以归类到阻塞式I/O,它与阻塞式I/O的区别在于阻塞的系统调用不同。而异步I/O的两个阶段都不会阻塞进程。

 

我们再来看看同步I/O与异步I/O(AIO),根据卷1的说明,同步I/O与异步I/O是由POSIX定义的两个术语:

同步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操作已经完成。

 

在Linux下有两种称为AIO的的接口。一个是由glibc提供,是由多线程来模拟:数据等待和数据复制的工作,由glibc创建线程来完成。数据复制完成后,执行I/O操作的线程通过回调函数的方式通知应用线程(严格来讲,这种方式不能算真正的AIO,因为用来执行实际I/O操作的线程还是阻塞在I/O操作上,只不过从应用进程的角度来看是异步方式的)。另一种是由内核提供的Kernel AIO,可以做到真正的内核异步通知(这种方式对读写方式,写入大小及偏移都有严格的要求),并且不支持网络I/O[1][2],其实现原理本质上与下面要介绍的IOCP类似。

 

还有一种称为IOCP(Input/Output Completion Port)的AIO。从实现原理上讲,IOCP做完I/O操作后,将结果封装成完成包(completion packet)入队到完成端口的队列(FIFO)中去,应用线程从队列中读取到完成消息后,处理后续逻辑。从这方面来讲,IOCP类似生产者-消费者模型:生产者为内核,收到应用线程的I/O请求后,等待数据可用,并将结果数据复制到应用线程指定的缓冲区中后,然后入队一个完成消息;消费者为应用线程,一开始向内核提交I/O请求,并在队列上等待内核的完成消息(只不过,IOCP对同时可运行的消费者有限制),收到完成消息后,进行后续处理[3]。

 

从上面对Linux kernel AIO以及IOCP的介绍可以看出,这两种异步I/O操作的完成通知是通过入队消息到消息队列的方式来完成的,应用进程必须阻塞在消息队列上来等待完成消息(别被这里的阻塞混淆,AIO定义中的阻塞是指实际的I/O操作)。

 

Reactor与Proactor模式就分别对应同步I/O和异步I/O[4]:Reactor是在事件就绪时通知应用进程,应用进程需要完成实际的I/O操作;而Proactor是在I/O操作已经完成的时候(数据就绪,并且已经拷贝到应用进程的缓冲区中,实际的I/O操作由操作系统来完成)通知应用进程。

 

AIO在服务器设计方面很少被用到[5],更多的使用在本地I/O方面[6]。

 

总结:

其实要搞清楚这些概念,主要是搞清楚这些概念描述的主体是什么:

阻塞或者非阻塞I/O主要是指I/O操作第一阶段的完成方式,即数据还未准备好的时候,应用进程的表现,如果这里进程挂起,则为阻塞I/O,否则为非阻塞I/O。

 

同步或者异步I/O主要是指实际I/O操作的完成方式,同步意味着由应用进程发起并完成I/O操作,I/O操作未完成前,会导致应用进程挂起;异步意味着应用进程只发出I/O请求,并接收完成通知,实际I/O操作由系统完成,I/O操作进行时,应用进程可以继续工作。

 

参考资料:

1. http://cnodejs.org/topic/4f16442ccae1f4aa270010a7/

2. http://lse.sourceforge.net/io/aio.html

3. http://60.251.1.52/taiwan/technet/sysinternals/information/iocompletionports.mspx

4. http://www.artima.com/articles/io_design_patterns2.html

5. http://www.kegel.com/c10k.html#aio

6. http://blog.yufeng.info/archives/741

  • 大小: 23.7 KB
1
3
分享到:
评论
1 楼 liusu 2013-09-04  
非常的清楚。。

AIO适用于CPU敏感的应用程序?

相关推荐

    详解socket阻塞与非阻塞,同步与异步、I/O模型

    主要介绍了详解socket阻塞与非阻塞,同步与异步、I/O模型,socket网络编程中的同步,异步,阻塞式,非阻塞式,有何联系与区别,本文将详细讲诉。

    socketjava源码-demo-sockets-io-nio-nio2:“Java套接字I/O:阻塞,非阻塞和异步”文章和源代码

    O:阻塞,非阻塞和异步 介绍 在描述I / O时,术语“非阻塞”和“异步”通常可以互换使用,但是它们之间存在显着差异。 本文描述了Java中非阻塞和异步套接字I / O操作之间的理论和实践差异。 套接字是通过TCP和UDP...

    网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO

    网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO

    浅谈socket同步和异步、阻塞和非阻塞、I/O模型

    在进行网络编程时,常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式 同步/异步主要针对C端: 同步:c端发出一个功能调用时,在没有得到结果之前,c端死等结果 例如:普通B/S模式(同步)...

    探索Java I/O 模型的演进

    阻塞和非阻塞又有什么区别?本文先从 Unix 的 I/O 模型讲起,介绍了5种常见的 I/O 模型。而后再引出 Java 的 I/O 模型的演进过程,并用实例说明如何选择合适的 Java I/O 模型来提高系统的并发量和可用性。,需要的...

    网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO.pdf

    同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问题其实不同的人给出的答案都可能不同,比如wiki,就认为asynchronous IO和non...

    高性能IO模型浅析

    (2)同步非阻塞IO(Non-blocking IO):默认创建的socket都是阻塞的,非阻塞IO要求socket被设置为NONBLOCK。注意这里所说的NIO并非Java的NIO(New IO)库。 (3)IO多路复用(IO Multiplexing):即经典的Reactor...

    Java NIO:浅析I/O模型

    下面本文先从同步和异步的概念 说起,然后接着阐述了阻塞和非阻塞的区别,接着介绍了阻塞IO和非阻塞IO的区别,然后介绍了同步IO和异步IO的区别,接下来介绍了5种IO模型,后介绍了两种和高性能IO设计相关的设计模式...

    PHP7中I/O模型内核剖析详解

    4.非阻塞:就是调用我(s端被调用者,函数),我(s端被调用者,函数)立即返回,得出结果后通知调用者 五种I/O模型 (1) 阻塞I/O (Blocking I/O) 当用户进程进行系统调用时,内核就开始了I/O的第一个阶段,准备数据...

    C++ boost::asio编程-同步TCP详解及实例代码

    boost.asio库是一个跨平台的网络及底层IO的C++编程库,它使用现代C++手法实现了统一的异步调用模型。 boost.asio库支持TCP、UDP、ICMP通信协议。 下面介绍同步TCP模式: 大家好!我是同步方式! 我的主要特点...

    基于javatcpsocket通信的拆包和装包源码-Netty-practice:Netty学习实践

    非阻塞I/O I/O复用 信号驱动的I/O 异步I/O Java I/O模型 同步阻塞IO 1:1同步阻塞IO通信模型 M:N形式的同步阻塞IO通信模型 非阻塞式IO模型(NIO) NIO+单线程Reactor模型 NIO+多线程Reactor模型 NIO+主从多线程Reactor...

    总结网络IO模型与select模型的Python实例讲解

    网络I/O模型 人多了,就会有问题。web刚出现的时候,光顾的人很少。近年来网络应用规模逐渐扩大,应用的架构... 非阻塞I/O(non-blocking I/O) 多路复用I/O(multiplexing I/O) 信号驱动式I/O(signal-driven I/O)

    2-Socket阻塞与非阻塞,同步与异步、IO模型-120412发布1

    1. 同步,就是我客户端(c端调用者)调用一个功能,该功能没有结束前,我(c端调用者)死等结果 2. 异步,就是我(c端调用者)调用一个功能,不需要知道该功能结

    特征:1、跨平台(Linux, Windows, MacOS, Solaris)2、高性能事件循环.rar

        在类unix系统中有五大I/O模型,依次为阻塞IO(BIO)、非阻塞IO(NIO)、IO多路复用(linux下有select、poll、epoll三种方案)、信号驱动IO、异步IO(前面四种都是同步IO),本文主要介绍常用的C的IO库,几乎都是...

    UNIX环境高级编程_第二版中文

    16.8 非阻塞和异步I/O  16.9 小结  习题  第17章 高级进程间通信  17.1 引言  17.2 基于STREAMS的管道  17.2.1 命名的STREAMS管道  17.2.2 唯一连接  17.3 UNIX域套接字  17.3.1 命名UNIX域套接...

    java-simple-reactor:java简单的reactor的模型

    3.I/O模型 同步阻塞IO:在此种方式下,用户进程在发起一个IO操作以后,必须等待IO操作的完成,只有当真正完成了IO操作以后,用户进程才能运行。JAVA传统的IO模型属于此种方式; 同步非阻塞IO:在此

    一种基于Netty框架的网络应用服务器设计方法

    Netty是一个异步的事件驱动的网络编程模型框架,使用Java NIO构建了Reactor模型,该模型是一种具有优良扩展性和性能的非阻塞异步模式,它同步等待多个I/O事件的到达,对其进行多路分离,派发给工作线程。Netty包括一...

    Node.js的特点和应用场景介绍

    Node.js借助事件驱动,非阻塞I/O模型变得轻量和高效,非常适合 运行在分布式设备的数据密集型实时应用。 1. 特点 1.1 异步I/O 所谓的异步I/O,是相对同步I/O而言的。程序执行过程中必然要进行很多I/O操作,如读写...

Global site tag (gtag.js) - Google Analytics