本文主要对UNIX的五种IO模型,特别是我们最常常用的epoll的工作原理做了简要介绍,总结了一下Java里面几种IO模型对应的实现方式。

Java网络编程

1. UNIX五种IO模型

1.1. IO

1.2. NIO

1.3. I/O多路复用(select, poll, Linux 2.6中改进的epoll)
1.3.1. 主要方式

  • select

  • poll
    为了解决select支持的fd大小为1024的问题,poll改变了fds的集合描述方式,使用了poll_fd而不是fd_set结构

  • epoll
    执行epoll_create,创建了红黑树和就绪链表
    执行epoll_ctl,如果增加socket句柄,则检查在红黑树中是否存在,存在立即返回,不存在则添加到红黑树,然后向内核注册回调函数,用于当中断事件来临时向准备就绪链表中插入数据
    执行epoll_wait时立刻返回准备就绪链表里的数据
    LT和ET模式(水平触发和边缘触发),LT模式下,只要一个句柄上的事件一次没有处理完,后面调用epoll_wait时还会返回这个句柄,而ET模式仅在第一次返回

1.3.2. 区别

1
2
3
select和poll每次调用都需要遍历整个fd,直到设备就绪,期间睡眠和唤醒多次交替,而epoll_wait执行的时候只需要遍历就绪链表中的节点
select/poll每次调用都需要把fd集合从用户态往内核态拷贝一次,而epoll只需要在调用epoll_ctl的时候拷贝一次
select支持的fd数量较小,默认是1024,而epoll里面fd的最大值为系统最多可打开的fd数目,这个数字一般远大于1024

1.4. 信号驱动I/O

1.5. AIO

2. IO

2.1. 面向流
2.2. 阻塞
2.3. 无Selector

3. NIO

3.1. 基本概念
3.1.1. 同步异步
关注事件发生时的行为
3.1.2. 阻塞非阻塞
关注等待事件时的状态

3.2. 组件
3.2.1. Channel

  • FileChannel
    文件

  • transferFrom
    将数据从源通道传输到FileChannel

  • transferTo
    将数据从FileChannel传输到其他Channel

  • DatagramChannel
    UDP

  • SocketChannel
    TCP

  • ServerSocket
    监听套接字

3.2.2. ByteBuffer

  • 属性
    Position
    Limit
    Capacity

  • 重要方法

  • flip
    读写模式切换

  • clear

  • compact
    类型

3.2.3. Scatter/Gather

  • Scatter
    一个Channel分散到多个Buffer

  • Gather
    多个Channel收集到一个Buffer

3.2.4. Selector
SelectionKey
就绪时间集合
Accept, Connect, Read, Write

3.2.5. Pipe
管道是2个线程间的单向数据连接
Source(读), Sink(写)

3.3. 特点
面向缓冲
非阻塞
选择器Selector

4. AIO

4.1. AsynchronousFileChannel
4.2. AsynchronousSocketChannel
4.3. AsynchronousServerSocketChannel
4.4. AsynchronousChannelGroup
处理IO的线程组
4.5. 监控/控制 异步操作
Future,Future.get
回调 CompletionHandler

Contents
  1. 1. 1. UNIX五种IO模型
  2. 2. 2. IO
  3. 3. 3. NIO
  4. 4. 4. AIO