没图,不分析API

Java中IO API的发展:
Socket -> SocketChannel -> AsynchronousSocketChannel
ServerSocket -> ServerSocketChannel -> AsynchronousServerSocketChannel

同步/阻塞 -> 同步/非阻塞(多路复用) -> 异步

想简单聊下多路复用。多路复用需要配合Reactor模式,前者解决技术上的问题,后者解决软件工程的问题。

技术上的问题,是将IO操作中等待和非等待的部分分开处理。我们都知道IO操作分为两个部分:
1、等待数据就绪
2、处理数据

众所周知的几种IO模型(阻塞、非阻塞、多路复用、信号驱动、异步)就是区别于这两个阶段,当需要处理很多连接的时候(高并发的情况),容易想到的是使用多线程技术,比如最简单的One-connection-Per-thread模式,但是因为等待数据不可避免,造成的结果是线程不停的休眠-唤醒的切换,导致CPU不堪重负。

IO复用的目的:将这两个阶段分开处理,让一个线程(而且是内核级别的线程)来处理所有的等待,一旦有相应的IO事件发生就通知继续完成IO操作,虽然仍然有阻塞和等待,但是等待总是发生在一个线程,这时使用多线程可以保证其他线程一旦唤醒就是处理数据,当然这需要非阻塞IO API的支持(比如非阻塞套接字)。Linux2.6之前的select,poll以及之后的epoll都是IO复用技术的实现。selectpoll基本一致,epoll是对它们的改进版本。但总的来说它们都还不是真正的异步IO,因为它们在IO读写的时候仍然是阻塞的、同步的(完成一件事后才能做另外一件事)。异步IO是指“处理数据”这一阶段也是非阻塞的。Windows上的IOCP(完成端口)才是真正的AIO,理论上它比Linux的epoll更先进。

至于select、poll和epoll的区别,推荐这篇文章:http://www.cnblogs.com/Anker/p/3265058.html。简单来说:select,poll无脑的轮询,忽略了高并发下,轮询本身成了瓶颈,而epoll使用回调实现了轮询真正需要处理的连接。

Reactor模式是为了我们更简单的使用IO复用技术。它是一种并发IO模式,其他的模式还有多进程,多线程等。Reactor本身也有很多变种,比如thread per request,worker thread,thread pool,multiple reactors...网上这方面的资料很多。虽然网上关于reactor和多线程模孰优孰劣还有争论(Reactor最明显的一个缺点是无法充分利用多核的优势),但是大部分高并发的框架或组建都是基于reactor的,比如MINA,Netty,再比如Redis,Nginx(有多个工作进程来充分利用多核的优势)。关于Java中的IO复用可以看Doug Lea大神的Scalable IO in Java(http://gee.cs.oswego.edu/dl/cpjslides/nio.pdf)。

至于JDK1.7中出现的Asynchronous I/O,只要是运行Linux上肯定无外乎epoll,那是不是可以说本质上仍然不是真正的异步IO呢?个人觉得异步这个概念是有粒度的,不可能做到完全的异步。JDK1.7中的AIO从编程的角度对程序员来说确是异步的,我们不用像在多路复用中那样自己去select了,我们需要做的就是在completion handlers中处理业务逻辑。

另外提一点:操作系统底层的IO操作都是异步的——IO中断,只不过同步更符合正常人的思维,更易于理解。

最后关于异步IO还想补充一点,虽然异步IO的第二阶段也是非阻塞的,但是仍然有优化空间。就是在数据从内核copy到用户空间这个过程,Netty就使用了Zero-Copy技术来优化这个步骤(http://my.oschina.net/plucury/blog/192577),另外还有MMAP。

欢迎斧正!

简单聊下IO复用的更多相关文章

  1. 简单聊下Unicode和UTF-8

    今晚听同事分享提到这个,简单总结下. ## Unicode字符集 Unicode的出现是因为ASCII等其他编码码不够用了,比如ASCII是英语为母语的人发明的,只要一个字节8位就能够表示26个英文字 ...

  2. 简单聊下.NET6 Minimal API的使用方式

    前言 随着.Net6的发布,微软也改进了对之前ASP.NET Core构建方式,使用了新的Minimal API模式.之前默认的方式是需要在Startup中注册IOC和中间件相关,但是在Minimal ...

  3. 一只简单的网络爬虫(基于linux C/C++)————浅谈并发(IO复用)模型

    Linux常用的并发模型 Linux 下设计并发网络程序,有典型的 Apache 模型( Process Per Connection ,简称 PPC ), TPC ( Thread Per Conn ...

  4. Libevent的IO复用技术和定时事件原理

    Libevent 是一个用C语言编写的.轻量级的开源高性能网络库,主要有以下几个亮点:事件驱动( event-driven),高性能;轻量级,专注于网络,不如 ACE 那么臃肿庞大:源代码相当精炼.易 ...

  5. IO复用(Reactor模式和Preactor模式)——用epoll来提高服务器并发能力

    上篇线程/进程并发服务器中提到,提高服务器性能在IO层需要关注两个地方,一个是文件描述符处理,一个是线程调度. IO复用是什么?IO即Input/Output,在网络编程中,文件描述符就是一种IO操作 ...

  6. 高级IO复用应用:聊天室程序

    简单的聊天室程序:客户端从标准输入输入数据后发送给服务端,服务端将用户发送来的数据转发给其它用户.这里采用IO复用poll技术.客户端采用了splice零拷贝.服务端采用了空间换时间(分配超大的用户数 ...

  7. Linux中的IO复用接口简介(文件监视?)

    I/O复用是Linux中的I/O模型之一.所谓I/O复用,指的是进程预先告诉内核,使得内核一旦发现进程指定的一个或多个I/O条件就绪,就通知进程进行处理,从而不会在单个I/O上导致阻塞. 在Linux ...

  8. IO复用,AIO,BIO,NIO,同步,异步,阻塞和非阻塞 区别参考

    参考https://www.cnblogs.com/aspirant/p/6877350.html?utm_source=itdadao&utm_medium=referral IO复用,AI ...

  9. IO复用,AIO,BIO,NIO,同步,异步,阻塞和非阻塞 区别(百度)

    如果面试问到IO操作,这篇文章提到的问题,基本是必问,百度的面试官问我三个问题 (1)什么是NIO(Non-blocked IO),AIO,BIO (2) java IO 与 NIO(New IO)的 ...

随机推荐

  1. Jenkins进阶系列之——02email-ext邮件通知模板

    发现一个很好的邮件通知模板,根据我的需求定制了一些.分享一下. Default Subject: 构建通知:${BUILD_STATUS} - ${PROJECT_NAME} - Build # ${ ...

  2. hugo-最好用的静态网站生成器

    hugo最好用的静态网站生成器 Hugo是由Go语言实现的静态网站生成器.简单.易用.高效.易扩展.快速部署. 快速开始 安装Hugo 1. 二进制安装(推荐:简单.快速) 到 Hugo Releas ...

  3. bt协议详解 DHT篇(上)

    bt协议详解 DHT篇(上) 最近开发了一个免费教程的网站,突然产生了仔细了解bt协议的想法,这篇文章是bt协议详解系列的第三篇,后续还会写一些关于搜索和索引的东西,都是在开发这个网站的过程中学习到的 ...

  4. 慢牛APP相关截图

    慢牛APP相关截图 第一和第二个版本都是基于Sencha Touch+Cordova开发,公众号是采用Angularjs+D3开发,第三个版本是采用React Native开发. 第一个版本 第二个版 ...

  5. PHP Yii2.0(一):环境搭建 & 问题集锦

    第一节 简单认识版本的异同 (1)版本说明 在安装和使用之前,我们需要知道 PHP Yii 有两个不同的版本(Yii 1.*或者Yii 2.*),这两个版本的目录结构不一样,其具体使用方式差异较大,因 ...

  6. [30分钟]MSSQL快速入门教程

    1.什么是SQL语句 sql语言:结构化的查询语言.(Structured Query Language),是关系数据库管理系统的标准语言. 它是一种解释语言:写一句执行一句,不需要整体编译执行.语法 ...

  7. centos6.5上安装Openfire 4.0.3

    更新时间:2016年11月9日 00:18:27 博主的安装环境 物理机:        Win7 SP1 64位 ip:192.168.111.1    (用于安装spark 2.8.1) VM虚拟 ...

  8. 我的第二个app上线:术购管家

    忙了两周写完的app,终于发布了,可是等上线竟然等了两周多,今天终于上线了,一路顺畅,没有被打回过...

  9. redis学习笔记——(4)

    一.概述: 在该系列的前几篇博客中,主要讲述的是与Redis数据类型相关的命令,如String.List.Set.Hashes和Sorted-Set.这些命令都具有一个共同点,即所有的操作都是针对与K ...

  10. Bootstrap3.0学习第十七轮(JavaScript插件——模态框)

    详情请查看http://aehyok.com/Blog/Detail/24.html 个人网站地址:aehyok.com QQ 技术群号:206058845,验证码为:aehyok 本文文章链接:ht ...