Linux I/O

目录

1、基础

1.1 Linux 网络 I/O模型简介

1.1.1 阻塞 I/O 模型

1.1.2 非阻塞 I/O 模型

1.1.3 I/O 复用模型

1.1.4 信号驱动 I/O 模型

1.1.5 异步 I/O 模型

1.2 I/O多路复用

1 概念

2 优点

3 应用场景

4 支持 I/O 多路复用的系统调用有:

2、Java IO演进

2.1 BIO

2.2 NIO

2.3 AIO


1、基础

Java1.4 之前,对 I/O 支持不完善,主要问题有:

  • 没有数据缓冲区,I/O 性能存在问题;
  • 没有 C 或者 C++ 中的 Channel 概念,只有输入和输出流;
  • 同步阻塞式 I/O 通信(BIO),通常会导致线程被长时间阻塞;
  • 支持的字符集有限,硬件的可移植性不好。

1.1 Linux 网络 I/O模型简介

Linux 的内核将所有外部设备都看做一个文件来操作,对一个文件的读写操作会调用内核提供的系统命令,返回一个 file descriptor(fd,文件描述符)。而对一个 socket 的读写也会有相应的描述符,称为 socketfd(socket 描述符),描述符就是一个数字,它指向内核中的一个结构体(文件路径,数据区等一些属性)。

UNIX 提供 5 种 I/O 模型(以套接字接口为例来说明

1.1.1 阻塞 I/O 模型

  • 一个应用进程等待一个套接字变为可读。
  • 从调用 recvfrom 开始,到可以处理数据这段时间,其实可以分为两个部分:
  • 第一部分是内核等待数据准备就绪的过程,第二部分是数据就绪后,内核将数据复制到应用进程的缓冲区的过程。
  • 这两部分都是内核在工作,而应用进程在这两部分都是处于阻塞状态,只等待,其他的什么也不做。
  • 所以说在调用开始后,直到可以处理数据这段时间,调用者一直阻塞。
  • 调用返回的时间:数据复制到应用进程的缓冲区,或发生错误。

1.1.2 非阻塞 I/O 模型

  • 一个应用进程等待一个套接字可读。
  • 从调用 recvfrom 开始,到可以处理数据这段时间,其实可以分为两个部分:
  • 第一部分是内核等待数据准备就绪的过程,第二部分是数据就绪后,内核将数据复制到应用进程的缓冲区的过程。
  • 对于第一部分来说,应用进程在发出系统调用之后,若内核没有准备好数据,那么会返回给应用进程一个 EWOULDBLOCK 错误;当应用进程收到这个错误之后,继续发出 recvfrom 的系统调用...,就这样,直到内核准备好数据。在这个部分,应用进程没有坐以待毙,而是不断询问内核。
  • 对于第二部分来说,内核将数据复制到应用进程的缓冲区,这段时间应用进程是阻塞的。
  • 所以,在发起系统调用,到能够处理数据这段时间,应用进程并不是坐以待毙,而是不断轮询,所以称之为非阻塞 I/O。

1.1.3 I/O 复用模型

  • 一个应用进程等待一个或多个套接字可读。
  • 这里也是分为两个部分:第一部分是内核等待数据准备就绪的过程,第二部分是数据就绪后,内核将数据复制到应用进程的缓冲区的过程。
  • 但是第一部分是通过 select 来侦测哪个进程数据准备好了,如果有一个进程数据准备好了,那么内核通知应用进程可以进行 recvfrom。这是与之前两种模型不同的地方。
  • 第二部分就是内核将数据复制到应用进程缓冲区的过程。

1.1.4 信号驱动 I/O 模型

  • 这里也是分为两个部分:第一部分是内核等待数据准备就绪的过程,第二部分是数据就绪后,内核将数据复制到应用进程的缓冲区的过程。
  • 对于第一部分:应用进程开启套接口信号驱动 I/O 功能,并通过系统调用 sigaction 执行一个信号处理函数,此系统调用立即返回,进程继续工作,它是非阻塞的。当数据准备就绪,内核就为该进程生成一个 SIGIO 信号,通过信号回调通知应用程序调用 recvfrom 来读取数据。这是它区别于其他模型的地方。
  • 对于第二部分,应用进程在做其他事情时,收到 SIGIO 信号,于是调用 recvfrom 进行数据处理。

1.1.5 异步 I/O 模型

  • 这里也是分为两个部分:第一部分是内核等待数据准备就绪的过程,第二部分是数据就绪后,内核将数据复制到应用进程的缓冲区的过程。
  • 对于第一部分,应用进程先告知内核启动某个操作,并让内核在整个操作完成后(包括将数据复制到用户自己的缓冲区)通知我们。
  • 对于第二部分,应用进程接到通知,发起 recvfrom 调用。
  • 异步 I/O 与信号驱动模型相比的区别:信号驱动模型,是内核准备好数据,但是还没有将数据复制到应用进程缓冲区中时,通知应用进程发起 recvfrom 调用。也就是信号驱动模型告诉我们何时开始一个 I/O。而异步 I/O,是内核将数据准备好,然后将数据复制到用户自己的缓冲区后,通知应用进程。也就是异步 I/O 通知我们 I/O操作何时完成。

1.2 I/O多路复用

1 概念

I/O 多路复用技术通过把多个 I/O 的阻塞复用到同一个 select 的阻塞上,从而使得系统在单线程的情况下可以同时处理多个客户端请求。

2 优点

与传统的多线程/多进程模型相比。I/O 多路复用的最大优势是系统开销小,系统不需要创建新的额外进程或线程,也不需要维护这些进程和线程的运行,降低了系统的维护工作量,节省了系统资源。

3 应用场景

  • 服务器需要同时处理多个处于监听状态或者多个连接状态的套接字;
  • 服务器需要同时处理多种网络协议的套接字。

4 支持 I/O 多路复用的系统调用有:

select、pselect、poll、epoll。

为了克服 select 的缺点,epoll 的改进:

1)支持一个进程打开的 socket 描述符(FD)不受限制(仅限于操作系统的最大文件句柄数)。

select 最大缺陷就是单个进程所打开的FD是有一定限制的,默认是 1024。

2)I/O 效率不会随着 FD 数目的增加而线性下降。

传统 select /poll 的另一个缺点,当拥有一个很大的 socket 集合时,由于网络延时或者链路空闲,任意时刻只有少部分的 socket是“活跃的”,但是 select/poll 每次都会线性扫描全部的集合,这导致效率呈线性下降。而 epoll 不存在这个问题,它只会对“活跃的”socket进行操作,这是因为在内核实现中,epoll 是根据每个 fd 上面的 callback 函数实现。只有“活跃的”socket才会主动调用callback函数,其他 idle状态的 socket 不会。

3)使用 mmap 加速内核与用户空间的消息传递。

4)epoll 的API 更加简单

2、Java IO演进

2.1 BIO

2.2 NIO

2.3 AIO

发布了95 篇原创文章 · 获赞 16 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/tiankong_12345/article/details/100095963