操作系统-理论-IO管理
IO管理概述
目的
外设管理目的
- 提高效率:提高IO访问效率,匹配CPU和多种不同处理速度的外设
- 方便使用:方便用户使用,对不同类型的设备统一使用方法,协调对设备的并发使用
- 方便控制:方便OS内部对设备的控制:增加和删除设备,适应新的设备类型
外设管理功能
- 提供设备使用的用户接口:命令接口和编程接口。
- 设备分配和释放:使用设备前,需要分配设备和相应的通道、控制器。
- 设备的访问和控制:包括并发访问和差错处理。
- IO缓冲和调度:目标是提高IO访问效率。
方式
CPU/Mem–接口适配器–设备控制器–外部设备
总线
总线是接入IO设备的主要方式。
总线带宽=频率*宽度,字节/秒
软件角度
用户进程在运行过程中,提出IO请求,一旦请求被操作系统接受,操作系统则负责完成该请求。
把硬件设备抽象为控制器。控制器中包含控制寄存器、状态寄存器,以及一些数据的寄存器。
从操作系统角度,是通过对这些寄存器进行相应的控制,达到控制设备的目的。
在OS中,IO 设备管理可直接从应用程序或文件系统得到请求,并负责完成这个请求。它具体包括:
- 逻辑IO:完成设备本身无关的操作,如设备分配,设备回收,数据准备等
- 设备驱动程序:通过读写设备控制器中的寄存器,完成对设备控制器的控制
- 中断服务程序:设备工作结束后负责向CPU 发中断信号
特点
IO性能经常成为系统性能的瓶颈;
操作系统庞大复杂的主要原因之一:资源多、杂,并发,均来自IO;
- 速度差异很大
- 控制接口复杂
- 传输单位不同
- 数据表示各异
- 错误条件多样
与其它功能联系紧密,特别是文件系统。
分类
按数据组织分类:
- 块设备:以数据块为单位存储、传输信息。传输速率较高、可寻址(随机读写)
- 字符设备:以字符为单位存储、传输信息。传输速率低、不可寻址
按用途分类:
- 存储设备:磁盘、磁带;
- 传输设备:网卡,Modem;
- 人机交互设备:显示器、键盘、鼠标。
从资源分配角度:
-
独占设备:在一段时间内只能由一个进程使用的设备。通常独占设备的传输速率比较慢。
打印机和磁带机都属于典型的独占设备。
-
共享设备:在一段时间内允许多个进程共同使用的设备。多个进程以交叉的方式来使用设备。资源利用率较高。
硬盘是典型的共享设备。
-
虚设备:在一类设备上模拟另一类设备,常用的方法是,用共享设备模拟独占设备,用高速设备模拟低速设备。
如:用Spooling技术将打印机变成共享设备。
目标和任务
- 按照用户请求,控制设备操作,完成IO设备与内存间的数据交换,最终完成用户的IO请求。
- 设备的分配与回收
- 记录设备的状态;
- 根据用户的请求和设备的类型,采用一定的分配算法,选择一条数据通路;
- 执行设备驱动程序,实现真正的IO操作;
- 设备中断处理:处理外部设备的中断;
- 缓冲区管理:管理不同的IO缓冲区。
- 设备的分配与回收
- 建立方便、统一的独立于设备的接口
- 方便性:向用户提供易于使用的外部设备的接口,使用户编程时不必考虑设备复杂的物理特性;
- 统一性:对不同的设备采用统一的操作方式,即在用户程序中使用逻辑设备。逻辑设备是对物理设备的抽象,它屏蔽了物理硬件的细节(设备繁多的物理特性、错误处理、不同IO过程的差异)。
- 提高CPU与设备、设备与设备之间的并行工作能力。尽可能减少CPU与IO间速度差异造成的整体性能开销,尽可能使CPU和设备都处于充分忙碌状态(均衡性)。
- 保护:设备传送或管理的数据应该是安全的、不被破坏的、保密的。
IO硬件组成
设备控制器、总线等
设备控制器
控制器的功能:
- 管理设备角度:
- 接收和识别CPU命令
- 设备状态的了解和报告
- 设备状态的了解和报告、设备地址识别
- 数据角度:
- 数据交换:CPU与控制器、控制器与设备
- 缓冲区
- 对设备传来的数据进行差错检测
组成:
- 控制器与CPU接口:数据寄存器、控制寄存器、状态寄存器,采用内存映射或专门的IO指令
- 控制器与设备接口:数据信号、控制信号、状态信号
- IO逻辑:用于实现CPU对IO设备的控制
IO端口地址
IO端口地址:接口电路中每个寄存器具有唯一的地址。
所有IO端口地址形成IO端口的地址空间(受OS保护)。
IO指令形式与IO地址是相互关联的,主要有以下形式:
-
内存映像编址(内存映像IO模式):
-
控制器的内存/寄存器作为物理内存空间的一部分
-
优点:
- 不需要特殊的保护机制来阻止用户进程进行相应的IO操作。
- 操作系统要避免把包含了控制寄存器的那部分地址空间放入用户的虚拟地址空间中。
- 可以引用内存的每一条指令都可以适用于引用控制寄存器,操作灵活。
-
缺点:不允许对一个控制寄存器的内容进行高速缓存,数据不能经过Cache,否则会有问题。
如果把设备控制寄存器进行了高速缓存,那么第一次引用的时候就把它放入了Cache。以后再对它的引用都是从Cache当中取值,而不会再去对设备进行相应的检测
-
-
IO独立编址(IO专用指令):
- Intel 体系架构in/out 指令
- 优点:
- 外设不占用内存的地址空间
- 编程时,易于区分是对内存操作还是对IO操作
- 缺点:
- IO端口操作的指令类型少,操作不灵活
IO控制方式
程序控制IO、中断驱动、DMA、通道
程序控制IO
程序控制IO:也称轮询或查询方式IO,它由CPU代表进程向IO模块发出指令,然后进入忙等状态,直到操作完成之后进程才能够继续执行。
- 应用程序提出了一个读数据的请求,发送给设备驱动程序。
- 设备驱动程序检查设备的状态:如果状态正常,就给设备发出相应的控制命令;
- 不断地轮询测试这个设备是否完成了这次执行过程;
- 设备控制器完成操作(将数据送入缓冲寄存器),把数据送给应用程序。应用程序继续进行相应的处理。
中断驱动
中断驱动:当IO操作结束后由设备控制器主动地来通知设备驱动程序操作结束,而不是设备驱动程序不断地去轮询看看设备的状态。
- 用户程序提出IO请求,发送给设备驱动程序
- 设备驱动程序检查设备的状态:
- 如果设备已经准备好,那么就==向设备发出控制命令==;
- 如果设备没有准备好,那么将状态记录在设备状态表中,CPU进行进程切换,继续其它工作。
- 设备完成工作后(将数据送入了缓冲寄存器)向CPU发中断信号,转入中断处理程序;
- 中断处理程序发现这是一个==正常地完成了控制命令的信号==后,把结果提交给设备管理程序;
- 设备管理程序会从设备状态表里查询是哪一个请求的完成,并==把相应的数据送到应用程序==;
- 通知应用程序可以继续执行。
直接存储访问模式DMA
DMA:直接存储器访问方式,是由一个专门的控制器来完成数据从内存到设备或者是从设备到内存的传输工作。
- 由程序设置DMA控制器中的若干寄存器值(如内存始址,传送字节数),然后发起IO操作;
- DMA控制器完成内存与外设的成批数据交换(==不经过CPU==);
- 在操作完成时由DMA控制器向CPU发出中断。
CPU只发起和结束相应的IO操作,在DMA工作期间,CPU不参与相应的IO操作,由DMA完成。
==每个设备占用一个DMA控制器,当设备增加时,需要增加新的DMA控制器。==
DMA中的寄存器:
- 命令/状态寄存器CR:用于接收从CPU发送来的IO命令,或有关控制信息,或设备的状态
- 内存地址寄存器MAR:
- 在输入时,它存放把数据从设备传送到内存的起始目标地址
- 在输出时,它存放由内存到设备的内存源地址
- 数据寄存器DR:用于暂存从设备到内存,或从内存到设备的数据
- 数据计数器DC:存放本次CPU要读或写的字(节)数
DMA与中断的区别
中断控制方式在每个数据传送完成后中断CPU;DMA控制方式是在要求传送的一批数据完成后中断CPU。
中断控制方式的数据传送是在中断处理时由CPU控制完成的,由于是程序切换,需要保护和恢复现场。
DMA方式下是由DMA控制器控制完成的,==在传输过程中不需要CPU干预==,DMA控制器直接在主存和IO设备之间传送数据,==只有开始和结束才需要CPU干预==。
程序中断方式具有对异常事件的处理能力,而DMA控制方式适用于数据块的传输。
IO通道
在DMA的基础上进一步减少了CPU的干预
IO通道:通道是一个特殊功能的处理器,它有自己的指令体系和程序专门负责数据输入输出的传输控制。CPU将“传输控制”的功能下放给通道,CPU只负责“数据处理”功能。
==通道与CPU分时使用内存==,实现了CPU内部运算与IO设备的并行工作。
由于有了自身的处理器,可以进一步减少CPU的干预。可执行由通道指令组成的通道程序,因此可以进行较为复杂的IO控制。通道程序通常由操作系统所构造,放在内存里。
执行一个通道程序可以完成几组IO操作,与DMA相比,减少了CPU干预。
IO通道分类
字节多路通道:以字节为单位交叉工作:当为一台设备传送一个字节后,立即转去为另一它设备传送一个字节;适用于连接打印机、终端等低速或中速的IO设备。
数组选择通道:以“组方式”工作,每次传送一批数据,传送速率很高,但在一段时间只能为一台设备服务。每当一个IO请求处理完之后,就选择另一台设备并为其服务;适用于连接磁盘、磁带等高速设备。
数组多路通道:综合了字节多路通道分时工作和选择通道传输速率高的特点;其实质是:对通道程序采用多道程序设计技术,使得与通道连接的设备可以并行工作。
IO通道与DMA的区别
==DMA方式:CPU每发出一条IO指令,只能完成一种IO操作,然后被中断。==
==通道方式:CPU只需要发出一条IO指令,就可以完成多种IO操作,之后被中断。==
DMA方式下,数据的传送方向、存放数据的内存起始地址和数据块长度都由CPU控制;
通道是一个特殊的处理器,有自己的指令和程序,通过执行通道程序实现对数据传输的控制,所以通道具有更强的独立处理IO的功能。
DMA控制器通常只能控制一台或者少数几台同类设备;而一个通道可同时控制多种设备。
IO软件的组成
分层设计
IO软件采用分层设计思想。每一层都执行OS所需的功能的一个子集,它依赖于更低一层所执行的更原始的功能,从而隐藏这些功能的细节;同时又给高一层提供服务。
- 较低层更多的考虑硬件的特性,并向较高层软件提供接口。
- 较高层不依赖于硬件,并向用户提供一个友好的、清晰的、简单的、功能更强的接口。
设备独立性
为了实现设备独立性而引入了逻辑设备和物理设备这两个概念。
在应用程序中,使用逻辑设备名称来请求使用某类设备,而系统在实际执行时,还必须使用物理设备名称。
系统需具有将逻辑设备名称转换为某物理设备名称的功能,类似于逻辑地址和物理地址的概念。
- 设备分配时的灵活性:
- 当进程以物理名称来请求使用指定设备时,如果该设备已经分配给其他进程或正在检修,而此时尽管还有几台其他的相同设备正在空闲,该进程仍然阻塞。
- 但若进程能够以逻辑设备名称来请求某类设备时,系统可立即将该类设备中的任一台分配给进程,仅当所有此类设备全部分配完毕时,进程才会阻塞。
- 易于实现IO重定向,用于IO操作的设备可以更换,而不必改变应用程序。
设备独立性的实现
逻辑设备表:为了实现设备的独立性,系统必须设置一张逻辑设备表LUT(Logical Unit Table),用于将应用程序中所使用的逻辑设备名映射为物理设备名。
每个表目中包含了三项:逻辑设备名、物理设备名、设备驱动程序的入口地址。通过逻辑设备名,系统可以查找LUT,便可找到物理设备和驱动程序。
设备驱动程序
与设备密切相关的代码放在设备驱动程序中,每个设备驱动程序处理一种设备类型。
设备驱动程序的任务是接收来自与设备无关的上层软件的抽象请求,并执行这个请求。
每一个控制器都设有一个或多个设备寄存器,用来存放向设备发送的命令和参数。设备驱动程序负责释放这些命令,并监督它们正确执行。
设备驱动程序的组成
-
驱动程序初始化函数
-
检测所要驱动的硬件设备是否存在、是否正常。
-
向操作系统登记该驱动程序的接口函数,该初始化函数在系统启动时安装入内核执行。
-
-
驱动程序卸载函数,申请设备函数,释放设备函数
-
IO操作函数:调用该子程序是系统调用的结果。
执行该部分程序时,系统仍认为是和调用进程属同一个进程,只是由用户态变成核心态。
- 对独占设备,包含启动IO的命令;
- 对共享设备,将IO请求挂入请求队列。
-
中断处理函数:系统来接收硬件中断,再由系统调用中断服务子程序。
带有一个或多个参数,以唯一标识请求服务的设备。
IO完成善后处理,一般是唤醒等待完成IO操作的阻塞进程;如果存在IO请求队列,则启动下一个IO请求。
设备驱动程序的共性
核心代码:==设备驱动是内核的一部分==,出错将导致系统的严重错误。
核心接口:设备驱动必须为内核提供一个标准接口。例如终端驱动为内核提供一个文件IO接口
核心机制与服务:可以使用标准的内核服务如内存分配、中断发送和等待队列等
动态可加载:在内核模块发出加载请求时加载;不再使用时卸载,内核能有效地利用系统资源
动态性:系统启动及设备驱动初始化时将查找它所控制的硬件设备。若某个设备的驱动为一个空过程时,不会对系统造成危害,只是会占用少量系统内存
和应用程序的区别
==驱动程序没有main,它以一个模块初始化函数作为入口==
驱动程序完成初始化之后不再运行,==等待系统调用==
驱动程序==不能使用标准C库==
IO缓冲管理
缓冲技术可提高外设利用率
- 匹配CPU与外设的不同处理速度
- 减少对CPU的中断次数
- 提高CPU和IO设备之间的并行性
单缓冲
每当用户进程发出一个IO请求时,操作系统便在主存中为之分配一个缓冲区。
记T为IO设备的输出时间,M为传冲去到用户进程的传送时间,C为用户进程的处理时间。
T和C是可以并行的,在面对较多数据时,缓冲区开始发挥作用,IO设备输出和用户进程处理是可以并行的
==但是缓冲区的传送和IO的输出是不能并行的==
双缓冲
两个缓冲区,CPU和外设都可以连续处理而无需等待对方。要求CPU和外设的速度相近。
使用双缓冲可以实现T和C+M的并行:在设备输入时,先将数据送入第一缓冲区,装满后便转向第二缓冲区。
双缓冲的使用提高了处理器和输入设备的并行操作的程度。
- 在双缓冲时,系统处理一块数据的时间可以粗略地认为是Max(C+M,T)
- 如果C<T,可使块设备连续输入
- 如果C>T,则可使CPU不必等待设备输入。
环形缓冲
若CPU和外设的处理速度差较大,双缓冲效果不够理想,因此引入了多缓冲机制,可将多个缓冲组织成循环缓冲形式。输入进程不断向空缓冲去输入数据,而计算进程则从中提取数据进行计算。
环形缓冲的组成为:
-
多个缓冲区,在循环缓冲区中包括多个缓冲区,每个缓冲区的大小相同
作为输入的多缓冲区可分为三种类型:
- 用于装输入数据的空缓冲区R
- 已装满数据的缓冲区G
- 计算进程正在使用的工作缓冲区C
-
多个指针,作为输入的缓冲区可设置三个指针
- 指示计算进程下一个可用缓冲区G的指针
Nextg
- 指示输入进程下次可用的空缓冲区R的指针
Nexti
- 指示计算进程正在使用的缓冲区C的指针
Current
- 指示计算进程下一个可用缓冲区G的指针
缓冲池
双缓冲和单缓冲均仅使用于某个特定的IO进程和计算进程,属于专用缓冲。当IO任务较多时会增加内存占用。
缓冲池由多个系统共用的缓冲区组成,在池中设置了多个可供若干个进程共享的缓冲区。
缓冲区按其使用状况可以形成三个队列:
- 空缓冲区队列
emq
- 装满输入数据的缓冲区队列
inq
- 装满输出数据的缓冲区队列
outq
缓冲区可以工作在收容输入、提取输入、收容输出、提取输出四种工作方式下。
- 收容输入:输入进程的暂存
- 在输入进程需要输入数据时,便调用
Getbuf(emp)
过程,从空缓冲队列的队首取出一个空缓冲区,作为收容输入工作缓冲hin
。 - 然后,把数据输入其中,装满后再调用
Putbuf(inq, hin)
过程,将该缓冲区挂在输入队列上。
- 在输入进程需要输入数据时,便调用
- 提取输入:计算进程的提取
- 当计算进程需要输入数据时,调用
Getbuf(inq)
过程,从输入队列队首取出一个缓冲区,作为提取输入工作缓冲区sin
- 计算进程从中提取数据
- 计算进程用完该数据后,再调用
Putbuf(emq, sin)
过程,将该缓冲区挂到空缓冲队列emq
上。
- 当计算进程需要输入数据时,调用
- 收容输出:计算进程的暂存
- 当计算进程需要输出时,调用
Getbuf(emq)
过程从空缓冲区队列emq
的队首取出一个空缓冲区,作为收容输出工作缓冲区hout
- 当其中装满输出数据后,又调用
Putbuf(outq, hout)
过程,将该缓冲区挂在outq
末尾。
- 当计算进程需要输出时,调用
- 提取输出:输出进程的提取
- 由输出进程调用
Getbuf(outq)
过程,从输出队列队首取出一个装满输出数据的缓冲区,作为提取输出工作缓冲区sout
- 在数据提取完后,再调用
Putbuf(emq, sout)
过程,将该缓冲区挂在空缓冲队列末尾。
- 由输出进程调用
IO设备管理
需解决进程间的外设共享问题,以提高外设资源的利用率。设备分配是对进程使用外设过程的管理。
有两种常见作法:
- 在进程间切换使用外设,如键盘和鼠标;
- 通过一个虚拟设备把外设与应用进程隔开,只由虚拟设备来使用设备。
设备分配的数据结构
设备分配依据的主要数据结构有:
- 设备控制表DCT
- 控制器控制表COCT
- 通道控制表CHCT
- 系统设备表SDT
设备控制表DCT
每个设备一张,描述设备特性和状态。反映设备的特性、设备和控制器的连接情况。
- 设备队列队首指针:凡因为请求本设备而未得到满足的进程,其PCB都应按照一定的策略排成一个队,称该队列为设备请求队列或简称设备队列,其队首指针指向队首PCB;
- 设备状态:当设备处于使用状态时,应该设备设置为忙/闲标志置为1;
- 控制器表指针:该指针指向该设备所连接的控制器的控制表COCT;
- 重复执行次数:外部设备在传送数据时,较容易发生数据传送错误。在许多系统中,如果发生传送错误,并不立即认为传送失败,而是令它重传,并由系统规定设备在工作中发生错误时应重复执行的次数。
控制器控制表COCT
每个设备控制器一张,描述IO控制器的配置和状态。
如DMA控制器所占用的中断号、DMA数据通道的分配。
通道控制表CHCT
每个通道一张,描述通道工作状态。
系统设备表SDT
反映系统中设备资源的状态,记录所有设备的状态及其设备控制表的入口。
- DCT指针:指向相应设备的DCT;
- 设备使用进程标识:正在使用该设备的进程标识;
- DCT信息:为引用方便而保存的DCT信息,如:设备标识、设备类型等;
单/多通路IO系统的设备分配
单/多通路:一个设备对应一/多个控制器,一个控制器对应一/多个通道。
-
分配设备:根据物理设备名查找系统设备表SDT,从中找到设备控制器表DCT
如果设备忙,则进入等待队列;否则,计算是否产生死锁,进行分配
-
分配设备控制器
-
将设备分配给进程后,在DCT中找到该设备相连的设备控制器表COCT
如果控制器空闲,则分配;否则,进入等待队列。
-
分配通道:从COCT中找到相连的通道控制表CHCT
如果通道空闲,则分配,否则,进入等待队列。
虚拟设备技术
SPOOLing
/虚拟设备技术:可把独享设备转变成具有共享特征的虚拟设备,从而提高设备利用率。
==在多道程序系统中,专门利用SPOOLing
程序来完成对设备的IO操作==。无需使用外围IO处理机。
例子:应用程序直接向打印机输出要15分钟,但向打印作业队列输出只需要1分钟,此后用户可以关闭打印进程进行其他工作。由打印机管理器完成15分钟的打印输出。
SPOOLing
的实现
SPOOLing
程序和外设进行数据交换:实际IO
SPOOLing
程序预先从外设读取数据并加以缓冲,在以后需要的时候输入到应用程序;SPOOLing
程序接受应用程序的输出数据并加以缓冲,在以后适当的时候输出到外设。
==应用程序进行IO操作时,只是和SPOOLing
程序交换数据==,可以称为“虚拟IO”。
应用程序实际上是从SPOOLing
程序的缓冲池中读出数据或把数据送入缓冲池,而不是跟实际的外设进行IO操作。
SPOOLing
的组成
==SPOOLing
系统由三部分组成:==
- 输入井和输出井:在磁盘上开辟的两个大存储空间
- 输入井是模拟脱机输入时的磁盘设备,用于暂存IO设备输入的数据
- 输出井是模拟脱机输出时的磁盘,用于暂存用户程序和输出数据。
- 输入缓冲区和输出缓冲区:缓和CPU与磁盘之间速度不匹配,在内存中开辟的两个缓冲区
- 输入缓冲区用于暂存由输入设备送来的数据,以后再传送到输入井。
- 输出缓冲区用于暂存从输出井送来的数据,以后再传送给输出设备。
- 输入进程
SPi
和输出进程SPo
:利用两个进程来模拟脱机IO时的外围控制机- 进程
SPi
模拟脱机输入时的外围控制机:将用户要求的数据从输入机通过输入缓冲区再送到输入井,当CPU需要输入数据时,直接从输入井读入内存; - 进程
SPo
模拟脱机输出时的外围控制机,把用户要求输出的数据先从内存送到输出井,待输出设备空闲时,再将输出井中的数据经过输出缓冲区送到输出设备上。
- 进程
特点
高速虚拟IO操作:
- 应用程序的虚拟IO比实际IO速度提高,缩短应用程序的执行时间
- 程序的虚拟IO操作时间和实际IO操作时间分离开来。
实现对独享设备的共享:由SPOOLing程序提供虚拟设备,可以对独享设备依次共享使用。
IO性能问题
解决IO性能问题的两个途径:
-
使CPU利用率尽可能不被IO降低
可以使用==缓冲技术==减少或缓解速度差异,同时使用异步IO使CPU不需要等待IO
-
使CPU尽可能摆脱IO
==使用DMA、通道等IO部件==让CPU摆脱IO操作的影响。
IO的过程
IO操作分为两个步骤:
- 磁盘把数据装载进内核的内存空间
- 内核的内存空间的数据copy到用户的内存空间中
从系统调用的开始到系统调用结束经过的步骤:
- 进程向内核发起一个系统调用;
- 内核接收到系统调用,知道是对文件的请求,向磁盘发送命令,读取文件;
- 磁盘接收到来着内核的命令后,把文件载入到内核的内存空间里面(可以是缓冲区);
- 内核的内存空间接收到数据之后,把数据copy到用户进程的内存空间(此过程是IO发生的地方);
- 进程内存空间得到数据后,给内核发送通知;
- 内核把接收到的通知回复给进程,此过程为唤醒进程,然后进程得到数据,进行下一步操作。
不同的IO模式
阻塞IO
阻塞IO:是指调用结果返回之前,当前线程会被挂起(线程进入睡眠状态)函数只有在得到结果之后,才会返回,才能继续执行。
IO的多路复用
IO多路复用:
- 工作进程调用一个管理IO的特殊库函数,此==库函数可以接受并管理多个IO请求,工作进程则可以同时等待多个IO请求==。
- 库函数将数据从内核空间拷贝到用户空间依然需要工作进程参与,这个阶段依旧会发生阻塞。
原本进程和系统内核直接沟通,现在在中间加一个IO复用select系统进行通知
非阻塞IO
非阻塞:进程发起IO调用后,就立即进行别的操作
事件驱动IO
进程发起调用,通过回调函数,内核会记住是哪个进程申请的。一旦第一段完成了,就可以向这个进程发起通知,这样第一段就是非阻塞的,进程不需要盲等了。但是第二段依然是阻塞的。
异步IO
无论第一第二段,不再向系统调用提出任何反馈,只有数据完全复制到服务进程内存中后,才向服务进程返回ok的信息。
其它时间,进程可以随意做其他事情,直到内核返回信息。
五种模式比较
![五种模式比较](C:\Users\Alex Bian\AppData\Roaming\Typora\typora-user-images\image-20240603195031316.png)