并发: IO模型

本文探讨了并发编程中的IO模型,从内核级别的同步IO与异步IO出发,详细介绍了阻塞式、非阻塞式、IO复用、信号驱动以及异步IO五种模型。重点讲解了Linux下的epoll作为IO复用技术的优势,以及网络IO并发模型中的BIO、NIO和AIO,如Netty、Node.js和Tomcat的实现。最后讨论了C10K问题的解决方案以及各种IO模型在实际应用中的表现。
摘要由CSDN通过智能技术生成

参考博客:

聊聊并发,Part 1:IO模型

1. 内核级别的IO

1.1 同步IO vs 异步IO

看过很多版本对于这些概念的描述,我觉得来自POSIX标准的这个判断准则最简单也最容易理解:

从发出IO操作请求开始到IO操作结束的过程中没有任何阻塞,就称为异步,否则为同步

1.2 IO 的两个阶段

那么,问题来了,从请求开始到操作完成,IO具体做了什么呢?其实,IO可以分为两个阶段,以socket的recv系统调用为例:

  • 第一阶段、等待数据就绪
  • 第二阶段、将数据从内核缓冲区复制到应用缓存区

2. IO 模型

IO模型在不断的演化和改进中,要做一个梳理并不容易,查阅了很多资料中对于IO模型的归纳,相比觉得《UNIX网络编程 卷1:套接字联网API》这本书中所总结的五种IO模型是最为清晰和合适的。

1) 阻塞式IO

最为常用的一种IO模型,整个IO操作从发起开始一直阻塞到完成,显然,这不够高效,但模型简单容易理解。目前,Linux的系统调用默认情况下大多是阻塞式的,socket的recv系统调用也是如此。

2) 非阻塞式IO

对于网络IO来说,IO的第一阶段往往需要比第二阶段花更多的时间,所以非阻塞式IO旨在将第一阶段非阻塞化,还是以recv系统调用为例,调用非阻塞式recv时,如果数据未ready,将直接返回,反之,就阻塞式地进行第二阶段的IO。在数据未就绪的情况下通常需要结合轮询机制,保证就绪状态的IO能够被及时的处理,这对CPU的浪费也是比较大的。非阻塞式的IO可以通过设置文件描述符O_NONBLOCK标识位实现,但它仅针对网络IO有效

3) IO Multiplexing

非阻塞式IO在遇到大量并发IO的时候(想想Web服务器的场景),CPU将忙于对所有文件描述符进行轮询检查,因为一次检查只能获知一个文件描述符的就绪状态,非常低效。随后,IO Multiplexing就实现了一次检查可以同时获取到多个文件描述符的就绪状态,通过这种方式可以大大提高就绪检查的效率。但需要指出的是,就绪检查本身是阻塞式的操作,在Linux平台,IO Multiplexing有多种实现,这里按照出现顺序来进行一一介绍。

  • select:通过select系统调用,需要检查的文件描述符数据被作为参数传入࿰
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值