1.用户空间&内核空间
现在操作系统都是采用虚拟存储器,操作系统将虚拟空间划分为两部分,一部分为内核空间,一部分为用户空间。
1.1. 内核空间:受保护的内存空间,只有操作系统可以访问;
1.2. 用户空间:供应用程序使用;
2.当一个read操作发生时,它会经历两个阶段:
2.1. 程序操作io
2.2. 等待数据准备 (Waiting for the data to be ready)
2.3. 将数据从内核拷贝到进程中 (Copying the data from the kernel to the process)
2.4. io数据返回
3.阻塞&非阻塞
阻塞与非阻塞是针对于操作io后得到的返回结果而言。
非阻塞: 调用io后能立即得到返回应答,即不需要等待2.2 2.3操作;否则为阻塞;
4.同步&异步
同步:进程调用io后得到的返回值为需要的数据,不需要等待(2.2或2.3);
异步:调用io后得到的是数据状态(未准备完成等),内核操作完成后主动通知进程(之间不做任何轮询等操作);
- 主要区别在于数据从内核空间拷贝到用户空间时,用户进程的状态;拷贝过程由io实现,进程不需要等待则为异步;否则为同步;
5.JAVA IO&NIO
IO:同步阻塞
NIO:同步非阻塞
AIO:也称为NIO2,异步非阻塞,jdk7
6.IO多路复用select、poll、epoll
这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程
1.java网络编程使用IO,每一个链接都需要一个单独的线程(对java来说是线程)服务,没有通信时线程阻塞;
2.select模式,一个线程可以为多个链接服务(多路复用);
a.所有链接都没有数据传输时,线程将其管理的所有连接(文件描述符)交给操作系统(描述符从用户空间复制到内核空间),由操作系统监控;进程阻塞;
b.当其中有一个连接有数据传输时,操作系统通知线程(描述符从内核空间复制到用户空间)
c.线程遍历所有连接(文件描述符)找到需要处理的连接;
2.1.主要缺点:
a.单个线程能监控的连接(文件描述符)有限为1024;
b.需要维护一个存放描述符的数据结构,内核与用户空间复制开销大;
c.遍历描述符时线性扫描;
3.poll
a.相比于select,取消了1024限制,但其他缺点仍然存在;
4.epoll
a.取消1024限制;
b.只将需要通信的连接返回给线程;
c.目前只有linux支持
- BIO同步阻塞、NIO同步非阻塞,AIO为异步非阻塞