Linux IO模型
linux的io分为两个阶段
- 等待数据准备好
- 从内核拷贝数据到用户态
io/阶段 | 等待数据准备好 | 从内核到用户态的数据拷贝 |
---|---|---|
blocking IO | 阻塞 | 阻塞 |
non-blocking IO | 异步(轮询) | 阻塞 |
IO multiplexing | 阻塞(一个线程管理多个链接) | 阻塞 |
signal driven IO | 异步(通知) | 阻塞 |
asynchronous IO | 异步 | 异步 |
blocking IO
blocking IO,阻塞IO,java中实现Socket和服务端为ServerSocket,每次来一个新链接都需要启动一个线程(可以用线程池来优化)每次当读数据的时候会阻塞,应用场景为:链接数目较小,且固定的架构,交互频繁,可预测的读,比如Mysql客户端,HttpClient,每次请求后都会有数据返回,像聊天服务器这种不知道何时会有消息就不太适合使用
为什么redis使用多路复用IO,不使用BIO?
reids是使用单线程处理各个链接的请求,如果使用BIO会产生大量并发线程,线程之间的切换与线程的同步开销会很大
思考:单线程处理BIO+队列与NIO的比较?

non-blocking IO
non-blocking IO,非阻塞IO(不是java中nio,java中nio对于的是linux模型中的io多路复用,java中nio可以理解为new io)

IO multiplexing
IO multiplexing,IO多路复用,java中NIO的实现,对应ServerSocketChannl,selector等,一个select为一个线程可以监听多个链接,有任意一个链接事件准备的时候就可以拿到,不需要每个socket都开启一个线程

signal driven IO
信号驱动式IO(signal-driven IO),就是让内核在描述符就绪时发送SIGIO信号通知用户进程。(使用较少)

asynchronous IO
异步IO(asynchronous IO)其实用得很少,在Linux 2.5 版本的内核中首次出现,在 2.6 版本的内核中才成为标准特性。

总结图

网友评论