看一遍就理解-IO模型详解 (看一遍就理解了的成语)
前言
大家好,我是程序员田螺。今天我们一起来学习IO模型。在本文开始前呢,先问问大家几个问题哈~
- 什么是IO呢?
- 什么是阻塞非阻塞IO?
- 什么是同步异步IO?
- 什么是IO多路复用?
- select/epoll跟IO模型有什么关系?
- 有几种经典IO模型呢?BIO、NIO、O到底有什么区别的?
如果这些问题,你都能很好答上的话,那恭喜你,你对IO的掌握已经很棒啦!那你跟田螺哥一起看完文章,再复习一下,加深印象吧~
如果你对这些问题模棱两可的话,那也没关系,看完文章,就理解啦!
什么是IO呢?
IO,英文全称是Input/Output,翻译过来就是输入/输出。平时我们听得挺多,就是什么磁盘IO,网络IO。那IO到底是什么呢?是不是有种懵懵懂懂的感觉呀,好像大概知道它是什么,又好像说不清楚。
IO,即输入/输出,到底谁是输入?谁是输出呢?IO如果脱离了主体,就会让人疑惑。
计算机角度的IO
我们常说的输入输出,比较直观的意思就是计算机的输入输出,计算机就是主体。
大家是否还记得,大学学计算机组成原理的时候,有个冯.诺依曼结构,它将计算机分成分为5个部分:运算器、控制器、存储器、输入设备、输出设备。
输入设备是向计算机输入数据和信息的设备,键盘,鼠标都属于输入设备;输出设备是计算机硬件系统的终端设备,用于接收计算机数据的输出显示,一般显示器、打印机属于输出设备。
![看一遍就理解](https://tyye.cn/zb_users/theme/tpure/style/images/lazyload.png)
鼠标、显示器这只是直观表面的输入输出,回到计算机架构来说,涉及计算机核心与其他设备间数据迁移的过程,就是IO。如磁盘IO,就是从磁盘读取数据到内存,这算一次输入,对应的,将内存中的数据写入磁盘,就算输出。这就是IO的本质。
操作系统的IO
我们要将内存中的数据写入到磁盘的话,主体会是什么呢?主体可能是一个应用程序,比如一个进程(假设网络传来二进制流,一个Java进程可以把它写入到磁盘)。
操作系统负责计算机的资源管理和进程的调度。我们电脑上跑着的应用程序,其实是需要经过操作系统,才能做一些特殊操作,如磁盘文件读写、内存的读写等等。因为这些都是比较危险的操作,不可以由应用程序乱来,只能交给底层操作系统来。
也就是说,你的应用程序要把数据写入磁盘,只能通过调用操作系统开放出来的API来操作。我们应用程序是跑在用户空间的,它不存在实质的IO过程,真正的IO是在操作系统执行的。即应用程序的IO操作分为两种动作:IO调用和IO执行。
IO调用是由进程(应用程序的运行态)发起,而IO执行是操作系统内核的工作。此时所说的IO是应用程序对操作系统IO功能的一次触发,即IO调用。
操作系统的一次IO过程应用程序发起的一次IO操作包含两个阶段:
1. IO调用:进程向操作系统发起IO请求,并阻塞在IO调用上,等待IO执行完成。
2. IO执行:操作系统内核完成IO操作,并唤醒进程。
其实IO就是把进程的内部数据转移到外部设备,或者把外部设备的数据迁移到进程内部。外部设备一般指硬盘、socket通讯的网卡。
一个完整的IO过程包括以下几个步骤:
1. 进程调用系统IO函数,将IO请求提交给内核。
2.内核检查请求是否合法,若合法则为该请求分配资源。
3. 内核为请求启动一个IO操作,并设置请求状态为"正在处理"。
4. 内核等待IO操作完成。
5. IO操作完成,内核将请求状态设置为"已完成",并唤醒等待的进程。
6. 进程继续执行,从系统IO函数返回。
阻塞IO模型
我们已经知道IO是什么啦,那什么是阻塞IO呢?假设应用程序的进程发起IO调用,但是如果内核的数据还没准备好的话,那应用程序进程就一直在阻塞等待,一直等到内核数据准备好了,从内核拷贝到用户空间,才返回成功提示,此次IO操作,称之为阻塞IO。
非阻塞IO模型
如果内核数据还没准备好,可以先返回错误信息给用户进程,让它不需要等待,而是通过轮询的方式再来请求。这就是非阻塞IO,流程图如下:
非阻塞IO的流程如下:
1. 进程调用系统IO函数,将IO请求提交给内核。
2. 内核检查请求是否合法,若合法则为该请求分配资源。
3. 内核为请求启动一个IO操作,并设置请求状态为"正在处理"。
4. 内核立即返回给进程,并设置错误码为EAGAIN或EWOULDBLOCK。
5. 进程通过轮询的方式不断查询IO操作的状态,直到状态变为"已完成"。
6. 进程继续执行,从系统IO函数返回。
非阻塞IO模型,简称NIO,Non-BlockingIO。它相对于阻塞IO,虽然大幅提升了性能,但是它依然存在性能问题,即频繁的轮询,导致频繁的系统调用,同样会消耗大量的CPU资源。
可以考虑IO复用模型,去解决这个问题。
IO多路复用模型
既然NIO无效的轮询会导致CPU资源消耗,我们等到内核数据准备好了,主动通知应用进程再去进行系统调用,那不就好了嘛?在操作系统内核中,维护一个事件表,每个事件对应一个文件描述符(描述一个打开的文件或套接字),当某个文件描述符就绪(有数据可读或可写),内核就会通过通知机制通知相应的进程或线程。
IO多路复用模型的流程如下:
1. 进程调用IO多路复用函数,将一个或多个文件描述符注册到内核事件表中。
2. 进程进入轮询等待,阻塞在IO多路复用函数上。
3. 当某个文件描述符就绪时,内核将该文件描述符加入到就绪事件队列中。
4. IO多路复用函数从就绪事件队列中取出就绪的文件描述符,并返回给进程。
5. 进程对就绪的文件描述符进行IO操作,如读写数据。
6. 进程继续执行,从IO多路复用函数返回。
IO多路复用模型的优点:
- 减少了系统调用次数,提高了程序性能。
- 可以同时监控多个文件描述符,提高了程序的并发能力。
IO多路复用模型的缺点:
- 实现比较复杂,需要对操作系统底层原理有较深的了解。
- 不同的操作系统有不同的IO多路复用实现,移植性差。
select/epoll与IO模型的关系
select/epoll是两种常见的IO多路复用模型的实现。select函数是POSIX标准中定义的IO多路复用函数,它可以通过一个文件描述符集合来监控文件描述符的可读、可写和异常状态。epoll函数是Linux内核中提供的IO多路复用函数,它比select函数更加高效,支持更大的文件描述符数量。select和epoll函数都提供了类似的功能,但是epoll函数在性能和效率方面优于
什么是IO模块
I/O模块可分为离散、模拟和特殊模块等多种类型,这些模块都可以安装在带有多个插槽的导轨或者机架上,每个模块插人其中一个插槽。导轨或者机架具有不同规格,插槽数分为4、8、12 不等。一般情况下,电源模块插在第一插槽内,编号为0,PLC插在第二插槽内,各种类型的输入输出模块插在其余插槽内。I/O模块导轨的背面安装带有连接器的印制电路板,可以将插入I/O模块的各插槽连接起来,插槽的上下边可以使插入的模块排成一条直线。
扩展资料:
在工业控制中,某些输入量是连续变化的模拟量(如压力、温度、流量、转速等),同时某些执行装置要求使用模拟量信号进行控制(如电动调节阀、伺服电机、变频器等),而PLC的处理器只能处理数字量。为了使PLC能够处理模拟量,必须实现模拟量和数字量之间的AD转换及DA转换。通过AD模块将检测装置输入的电压、电流模拟量转换为数字量传送给PLC。
什么是“同步IO”和“异步IO”?
同步IO在同一时刻只允许一个IO操作,也就是说对于同一个文件句柄的IO操作是序列化的,即使使用两个线程也不能同时对同一个文件句柄同时发出读写操作。重叠IO允许一个或多个线程同时发出IO请求。
异步IO的概念和同步IO相对。当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。在一个CPU密集型的应用中,有一些需要处理的数据可能放在磁盘上。预先知道这些数 据的位置,所以预先发起异步IO读请求。等到真正需要用到这些数据的时候,再等待异步IO完成。使用了异步IO,在发起IO请求到实际使用数据这段时间 内,程序还可以继续做其他事情。
免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。