【Linux高级IO】五种IO模型
📝个人主页🌹:Eternity._
⏩收录专栏⏪:Linux “ 登神长阶 ”
🌹🌹期待您的关注 🌹🌹
❀ Linux高级IO
- 重新理解IO
- I/O模型
- 阻塞式IO
- 非阻塞式IO
- 信号驱动IO
- IO多路转接
- 异步IO
- 同步通信 vs 异步通信
- 阻塞 vs 非阻塞
- 理解这四者的关系
- 总结
前言: 在信息技术日新月异的今天,Linux操作系统以其强大的稳定性和灵活性,成为了服务器、嵌入式系统以及众多开发者心中的首选平台。而在Linux系统的广阔天地中,I/O(输入/输出)操作无疑是连接用户与硬件、软件之间的桥梁,其性能的优化直接关系到整个系统的响应速度和数据处理能力。
深入探索Linux的I/O模型,我们不难发现,这些模型不仅仅是数据流动的通道,更是理解系统并发处理、资源调度以及性能调优的关键所在。从传统的阻塞I/O到现代的非阻塞I/O、I/O复用、信号驱动I/O乃至异步I/O,每一种模型都代表着不同的设计理念和技术进步,它们在不同的应用场景中发挥着各自的优势。
本文旨在带领读者踏上一段探索Linux高级I/O模型的旅程,通过详细剖析五种主流的I/O模型——阻塞I/O、非阻塞I/O、I/O复用(select/poll/epoll)、信号驱动I/O以及异步I/O,揭示它们的工作原理、实现机制以及在实际开发中的应用场景。我们将从理论到实践,逐步深入,让读者不仅能够理解这些模型的基本概念,更能掌握如何在具体项目中灵活运用它们,以实现更高效、更可靠的I/O操作。
让我们一同开启这段充满挑战与收获的旅程,探索Linux高级I/O模型的奥秘,为打造更加出色的系统应用奠定坚实的基础。
重新理解IO
我们在之前学习的基础IO时,我们就提到过IO在本质上就是文件的拷贝,在之前提到的IO中,input,output,read,recv需要访问外设,效率肯定不会有多高
当使用read和recv时:
- 如果底层缓冲区没有数据,read/recv函数会阻塞,等待我们输入数据;
- 如果底层缓冲区有数据, read/recv函数就会拷贝;
也可以说
IO = 等待 + 拷贝
因此在IO的效率上,等待是衡量IO是否高效的重要标准,高效的IO就是让等待的比重降低,减少IO类接口的等待,下面正式来介绍五种IO模型了解高级IO
钓鱼例子:
I/O模型
阻塞式IO
阻塞IO: 在内核将数据准备好之前,系统调用会一直等待,所有的套接字默认都是阻塞方式,因此阻塞IO是最常见的IO模型
对照钓鱼例子,阻塞IO就是你去河边钓鱼,只拿一根鱼竿等于上钩,并且时刻盯着水面
非阻塞式IO
非阻塞IO: 如果内核还未将数据准备好,系统不会像阻塞式IO一样进行等待数据,系统调用会直接返回,并且返回EWOULDBLOCK错误码
非阻塞IO往往需要程序员循环的方式反复尝试读写文件描述符,这个过程称为
轮询
。这对CPU来说是较大的浪费,一般只有特定场景下才使用
信号驱动IO
信号驱动IO: 内核将数据准备好的时候,使用SIGIO信号通知应用程序进行IO操作
IO多路转接
IO多路转接: 从流程图上看起来和阻塞IO类似. 实际上最核心在于IO多路转接能够同时等待多个文件描述符的就绪状态
异步IO
异步IO: 由内核在数据拷贝完成时,通知应用程序(而信号驱动是告诉应用程序何时可以开始拷贝数据)
任何IO过程中,都包含两个步骤:
第一是等待,第二是拷贝
。而且在实际的应用场景中,等待消耗的时间往往都远远高于拷贝的时间,让IO更高效,最核心的办法就是让等待的时间尽量少
同步通信 vs 异步通信
同步和异步关注的是消息通信机制:
- 所谓同步,就是在发出一个调用时,在没有得到结果之前,该调用就不返回,但是一旦调用返回,就得
到返回值了,换句话说,就是由调用者主动等待这个调用的结果- 异步则是相反,调用在发出之后,这个调用就直接返回了,所以没有返回结果; 换句话说,当一个异步
过程调用发出后,调用者不会立刻得到结果; 而是在调用发出后,被调用者通过状态、通知来通知调用
者,或通过回调函数处理这个调用
我们在之前讲到多进程与多线程的时候,也提到过 同步与互斥,但是在 IO中讲到的同步通信 与进程之间的同步是两个不一样的概念
- 进程/线程同步也是进程/线程之间直接的制约关系
- 是为完成某种任务而建立的两个或多个线程,这个线程需要在某些位置上协调他们的工作次序而等待、
传递信息所产生的制约关系,尤其是在访问临界资源的时候
阻塞 vs 非阻塞
阻塞和非阻塞关注的是程序在等待调用结果时的状态:
- 阻塞调用是指调用结果返回之前,当前线程会被挂起. 调用线程只有在得到结果之后才会返回.
- 非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程
理解这四者的关系
- 阻塞与非阻塞是操作模式:它们描述了进程(或线程)在等待某个条件满足时是否进入等待状态。阻塞操作会使进程(或线程)等待,而非阻塞操作则不会。
- 同步与异步是通信方式:它们描述了数据传输和任务执行的时序关系。同步通信要求发送方和接收方按照相同的时钟频率或时序进行数据传输,而异步通信则允许发送方和接收方独立地进行数据传输和任务执行。
阻塞与非阻塞描述了操作模式,而同步与异步描述了通信方式。这四者之间的关系可以通过它们的定义、特性以及相互之间的区别和联系来理解。在实际应用中,非阻塞异步通信通常是最优的选择,因为它能够提高系统的并发处理能力和响应速度。
总结
随着本文的收尾,我们共同完成了对Linux高级I/O模型中五种核心机制的深入探索。从阻塞I/O的直观理解,到非阻塞I/O的初步尝试,再到I/O复用、信号驱动I/O及异步I/O的复杂实现与应用,每一步都见证了技术的不断演进与我们对系统性能追求的深化。
在这个过程中,我们不仅学习了各种I/O模型的具体实现原理,更重要的是,我们学会了如何根据实际应用场景选择合适的I/O模型,以优化系统性能,提升用户体验。从高并发服务器的设计,到实时数据处理系统的开发,再到嵌入式系统的性能调优,每一种I/O模型都有其独特的价值和应用场景。
让我们携手共进,为推动Linux技术的发展和应用贡献自己的力量!
希望本文能够为你提供有益的参考和启示,让我们一起在编程的道路上不断前行!
谢谢大家支持本篇到这里就结束了,祝大家天天开心!