转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6543960.htmlhtml
一:事件分离器编程
在IO读写时,把 IO请求 与 读写操做 分离调配进行,须要用到事件分离器。根据处理机制的不一样,事件分离器又分为:同步的Reactor和异步的Proactor。ruby
Reactor模型:并发
- 应用程序在事件分离器注册 读就绪事件 和 读就绪事件处理器 - 事件分离器等待读就绪事件发生 - 读就绪事件发生,激活事件分离器,分离器调用 读就绪事件处理器(即:能够进行读操做了,开始读) - 读事件处理器开始进行读操做,把读到的数据提供给程序使用
Proactor模型:异步
- 应用程序在事件分离器注册 读完成事件 和 读完成事件处理器,并向操做系统发出异步读请求
socket
- 事件分离器等待操做系统完成读取
性能
- 在分离器等待过程当中,操做系统利用并行的内核线程执行实际的读操做,并将结果数据存入用户自定义缓冲区,最后通知事件分离器读操做完成
spa
- 事件分离器监听到 读完成事件 后,激活 读完成事件的处理器
操作系统
- 读完成事件处理器 处理用户自定义缓冲区中的数据给应用程序使用
线程
同步和异步的区别就在于 读 操做由谁完成:同步的Reactor是指程序发出读请求后,由分离器监听到能够进行读操做时(须要得到读操做条件)通知事件处理器进行读操做,异步的Proactor是指程序发出读请求后,操做系统马上异步地进行读操做了,读完以后在通知分离器,分离器激活处理器直接取用已读到的数据。
二:同步阻塞IO(BIO)
咱们熟知的Socket编程就是BIO,一个socket链接一个处理线程(这个线程负责这个Socket链接的一系列数据传输操做)。阻塞的缘由在于:操做系统容许的线程数量是有限的,多个socket申请与服务端创建链接时,服务端不能提供相应数量的处理线程,没有分配处处理线程的链接就会阻塞等待或被拒绝。
三:同步非阻塞IO(NIO)
New IO是对BIO的改进,基于Reactor模型。咱们知道,一个socket链接只有在特色时候才会发生数据传输IO操做,大部分时间这个“数据通道”是空闲的,但仍是占用着线程。NIO做出的改进就是“一个请求一个线程”,在链接到服务端的众多socket中,只有须要进行IO操做的才能获取服务端的处理线程进行IO。这样就不会由于线程不够用而限制了socket的接入。客户端的socket链接到服务端时,就会在事件分离器注册一个 IO请求事件 和 IO 事件处理器。在该链接发生IO请求时,IO事件处理器就会启动一个线程来处理这个IO请求,不断尝试获取系统的IO的使用权限,一旦成功(即:能够进行IO),则通知这个socket进行IO数据传输。
NIO还提供了两个新概念:Buffer和Channel
Buffer: – 是一块连续的内存块。 – 是 NIO 数据读或写的中转地。 Channel: – 数据的源头或者数据的目的地 – 用于向 buffer 提供数据或者读取 buffer 数据 ,buffer 对象的惟一接口。 – 异步 I/O 支持
Buffer做为IO流中数据的缓冲区,而Channel则做为socket的IO流与Buffer的传输通道。客户端socket与服务端socket之间的IO传输不直接把数据交给CPU使用,
而是先通过Channel通道把数据保存到Buffer,而后CPU直接从Buffer区读写数据,一次能够读写更多的内容。
使用Buffer提升IO效率的缘由(这里与IO流里面的BufferedXXStream、BufferedReader、BufferedWriter提升性能的原理同样):IO的耗时主要花在数据传输的路上,普通的IO是一个字节一个字节地传输,
而采用了Buffer的话,经过Buffer封装的方法(好比一次读一行,则以行为单位传输而不是一个字节一次进行传输)就能够实现“一大块字节”的传输。好比:IO就是送快递,普通IO是一个快递跑一趟,采用了Buffer的IO就是一车跑一趟。很明显,buffer效率更高,花在传输路上
的时间大大缩短。
四:异步阻塞IO(AIO)
NIO是同步的IO,是由于程序须要IO操做时,必须得到了IO权限后亲自进行IO操做才能进行下一步操做。AIO是对NIO的改进(因此AIO又叫NIO.2),它是基于Proactor模型的。每一个socket链接在事件分离器注册 IO完成事件 和 IO完成事件处理器。程序须要进行IO时,向分离器发出IO请求并把所用的Buffer区域告知分离器,分离器通知操做系统进行IO操做,操做系统本身不断尝试获取IO权限并进行IO操做(数据保存在Buffer区),操做完成后通知分离器;分离器检测到 IO完成事件,则激活 IO完成事件处理器,处理器会通知程序说“IO已完成”,程序知道后就直接从Buffer区进行数据的读写。
也就是说:AIO是发出IO请求后,由操做系统本身去获取IO权限并进行IO操做;NIO则是发出IO请求后,由线程不断尝试获取IO权限,获取到后通知应用程序本身进行IO操做。