网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
一、程序执行
程序执行是指程序在计算机中的运行过程。程序的执行可以用前趋图表示,程序的执行方式有顺序执行和并发执行两种。
1. 前趋图
前趋图是一个有向无循环图。图中的每个节点可用于表示一条语句、一个程序段等;节点间的有向边表示在两个节点之间存在的前趋关系。如Pi→Pj,称Pi是Pj的前趋,而Pj是Pi的后继。在前趋图中,没有前趋的节点称为初始节点,没有后继的节点称为终止节点。应当注意的是,前趋图中不能存在循环。
在上图所示的前趋图中存在下述前趋关系: P1→P2,P1→P3,P2→P4,P3→P4,P4→P5。
2. 程序的顺序执行
(1)程序顺序执行的概念
一个较大的程序通常由若干个操作组成。程序在执行时,必须按照某种先后次序逐个执行操作,只有当前一个操作执行完后,才能执行后一个操作。
(2)程序顺序执行的特征
- 顺序性。严格按照程序所规定的顺序执行。
- 封闭性。程序在封闭的环境下执行,其执行结果不受外界因素的影响。
- 确定性。程序执行的结果与它的执行速度无关,不会影响到最终结果。
- 可再现性。只要程序执行的环境和初始条件相同,都将获得相同的结果。
3. 程序的并发执行
(1)程序并发执行的概念
在处理一批程序时,它们之间有时并不存在严格的执行次序,可以并发执行。
程序并发执行时的前趋图,如下图所示。
(2)程序并发执行的特征
- 间断性。在程序并发执行时,它们之间共享资源或相互合作,形成了相互制约的关系,表现为“执行—暂停执行—执行”的间断性活动规律。
- 失去封闭性。程序并发执行时,多个程序共享系统中的各种资源,致使程序的运行失去了封闭性。这样,一个程序在执行时,必然会受到其他程序的影响。
- 不可再现性。即使并发程序执行的环境和初始条件相同,程序多次执行或以不同的方式执行都可能获得不相同的结果。
- 资源共享性。系统中的硬件资源(CPU、内存和I/O设备等)和软件资源(系统程序和数据集等)为多个用户或作业共同使用。
- 程序和计算不再一一对应。
二、进程的描述
(一)、进程的概念
进程的组成:是由PCB、程序段、数据段组成。
PCB是给操作系统用的,而程序段和数据段是给进程自己用的,与进程自身的运行逻辑有关。
1. 进程的定义
关于进程的定义有以下一些描述:
(1)进程是程序的一次执行。
(2)进程可以定义为一个数据结构及能在其上进行操作的一个程序。
(3)进程是程序在一个数据集合上的运行过程,是系统资源分配和调度的一个独立单位。
据此,可以把“进程”定义为:一个程序在一个数据集合上的一次运行过程。所以一个程序在不同数据集合上运行,乃至一个程序在同样数据集合上的多次运行都是不同的进程。
可将进程定义为:进程是进程实体的一次运行过程,是系统进行资源分配和调度的独立单位。
当进程创建时,操作系统会给该进程分配唯一的身份证号——PID
2. 进程的特征
进程与传统的程序是截然不同的两个概念,它具有五个基本特征,从这五个特征可以看到进程与程序的巨大差异。
(1)动态性
动态性是进程的最基本特征,它表现为“进程因创建而产生,因调度而执行,因得不到资源而暂停,以及因撤销而消亡”。因此,进程具有一定的生命周期,其状态也会不断发生变化,是一个动态实体。而程序仅是一组指令的集合,并且可以一成不变地存放在某种介质上,是一个静态实体。
(2)并发性
进程的并发性是指多个进程在一段时间内同时运行,交替使用处理器的情况。并发性是进程也是操作系统的重要特征。
(3)独立性
独立性是指进程实体是一个能独立运行的基本单位,同时也是独立获得资源和独立调度的基本单位。没有创建进程的程序,是不能参加运行的。
(4)异步性
异步性是指系统中的进程按照各自独立的、不可预知的速度向前推进,即进程按照异步方式运行。正因如此,将导致执行的不可再现性。因此,在操作系统中必须采取相应的措施来保证进程之间能够协调运行。
(5)结构性
进程的结构性是指在结构上进程实体由程序段、数据段和进程控制块组成,这三部分也统称为“进程映像”。
(二)、进程的状态极其转换
系统中的诸多进程并发运行,并因竞争系统资源而相互依赖相互制约,因而进程执行时呈现了“运行—暂停—运行”的间断性。进程执行时的间断性可用进程的状态及其状态的转换来描述。
1. 进程的三种基本状态
通常,一个进程必须有就绪、运行和等待三种基本状态。
(1)就绪状态
当进程已分配到除处理器(CPU)以外的所有必要资源后,只要再获得处理器就可以立即执行,这时进程的状态称为就绪状态。
在一个系统里,可以有多个进程同时处于就绪状态,通常把这些就绪进程排成一个或多个队列,称为就绪队列。
(2)运行状态
处于就绪状态的进程一旦获得了处理器,就可以运行,进程状态也就处于运行状态。
在单处理器系统中,只能有一个进程处于运行状态。在多处理器系统中,可能有多个进程处于运行状态。
(3)等待状态
正在运行的进程因为发生某些事件(如请求输入/输出、申请额外空间等)而暂停运行,这种受阻暂停的状态称为等待状态。
通常将处于等待状态的进程排成一个队列,称为等待队列。在有些系统中也会按照等待原因的不同将处于等待状态的进程排成多个队列。
2. 进程状态的转换
(三)、进程的挂起状态
1. 挂起状态的引入
在很多系统中,进程只有上述三种基本状态。但在另一些系统中,由于某种需要又增加了一些新的进程状态,其中最重要最常见的是挂起状态。
引入挂起状态主要是基于下列需求:
(1)用户的需求;
(2)父进程的需求;
(3)操作系统的需求;
(4)对换的需求;
引入挂起状态后的进程状态转换过程如下图所示。
(四)、进程控制块PCB
1. 进程控制块的作用
进程控制块PCB(Process Control Block)是进程实体的重要组成部分,是操作系统中最重要的记录型数据。在进程控制块中记录了操作系统所需要的、用于描述进程情况及控制进程运行所需要的全部信息。换句话说,在进程的整个生命周期中,操作系统都要通过进程的PCB来对并发运行的进程进行管理和控制。
由此看来,进程控制块是系统对进程控制采用的数据结构。系统是根据进程的PCB而感知进程存在的。所以,进程控制块是进程存在的唯一标志。 PCB可以被多个系统模块读取和修改,如调度模块、资源分配模块、中断处理模块、监督和分析模块等。因为PCB经常被系统访问,因此常驻主存。系统把所有的PCB组织成若干个链表(或队列),存放在操作系统中专门开辟的PCB区内。
2. 进程控制块的内容
(1)进程标志信息
进程标识符用于标识一个进程,通常有外部标识符和内部标识符两种。
① 外部标识符:
由进程创建者命名,通常是由字母、数字所组成的一个字符串,在用户(进程)访问该进程时使用。外部标识符都便于记忆,如计算进程、打印进程、发送进程、接收进程等。
② 内部标识符
为方便系统使用而设置的。操作系统为每一个进程赋予唯一的一个整数,把它作为内部标识符。内部标识符通常就是一个进程的序号。
(2)说明信息(进程调度信息)
说明信息是与进程调度有关的状态信息,它包括:
- 进程状态。它指明进程当前的状态,作为进程调度和对换时的依据。
- 优先权高的进程将优先获得处理器。
- 进程调度所需的其他信息。其内容与所采用的进程调度算法有关,如进 程等待时间、进程已运行时间等。
- 等待事件是指进程由运行状态转变为等待状态时所等待发生的事件,即等待原因。
(3)现场信息(处理器状态信息)
现场信息是用于保留进程存放在处理器中的各种信息,主要由处理器中的各个寄存器的内容组成。尤其是当进程暂停运行时,这些寄存器内的信息将被保存在PCB里,当该进程重新运行时,能从上次停止的地方继续运行。
- 通用寄存器。其中的内容可以被用户程序访问,用于暂存信息。
- 指令计数器。用于存放要访问的下一条指令的地址。
- 程序状态字。用于保存当前处理器的状态信息,如运行方式、中断屏蔽标志等。
- 用户栈指针。每个用户进程都有一个或若干个与之相关的关系栈,用于存放过程和系统调用参数及调用地址,栈指针指向堆栈的栈顶。
(4)管理信息(进程控制信息)
管理信息包括进程资源、控制机制等一些进程运行所需要的信息。
- 程序和数据的地址。它是指该进程的程序和数据所在的主存和外存地址,以便该进程再次运行时,能够找到程序和数据。
- 进程同步和通信机制。它是指实现进程同步和进程通信时所采用的机制,如消息队列指针、信号量等。
- 资源清单。该清单中存放有除CPU以外,进程所需的全部资源和已经分配到的资源。
- 链接指针。它将指向该进程所在队列的下一个进程的PCB的首地址。
(5)进程控制块的组织方式
(1)链接方式
把具有相同状态的PCB用链接指针链接成队列,如就绪队列、等待队列和空闲队列等。就绪队列中的PCB将按照相应的进程调度算法进行排序。而等待队列也可以根据等待原因的不同,将处于等待状态的进程的PCB排成等待I/O队列、等待主存队列等多个队列。
(2)索引方式
系统根据各个进程的状态建立不同的索引表,如就绪索引表、等待索引表等,并把各个索引表在主存的首地址记录在主存中的专用单元里,也可以称为表指针。在每个索引表的表目中,记录着具有相同状态的各个PCB在表中的地址。
(6)进程控制原语
原语是指具有特定功能的不被中断的过程。它主要用于实现操作系统的一些专门控制操作。用于进程控制的原语有:
- (1)创建原语 用于为一个进程分配工作区和建立PCB,置该进程为就绪状态。
- (2)撤销原语 用于一个进程工作结束后,收回它的工作区和PCB。
- (3)等待原语 用于进程在运行过程中发生等待事件时,把进程的状态改为等待状态。
- (4)唤醒原语 用于当进程等待的事件结束时,把进程的状态改为就绪状态。
三、进程控制
(一)操作系统内核
核心态:又称管态、系统态,是操作系统管理程序执行时计算机所处的状态。这种状态具有较高的特权,能执行一切指令,访问所有的寄存器和存储器。
用户态:又称目态,是用户执行程序时计算机所处的状态。这种状态具有较低的特权,只有执行规定的指令,访问指定的寄存器和存储器。
用户态和内核态是操作系统中的两种不同的运行级别。用户态是指应用程序运行时所处的状态,而内核态是指操作系统运行时所处的状态。在用户态下,应用程序可以访问自己的内存空间和一些受限制的系统资源,但不能直接访问硬件设备和操作系统的核心功能。而在内核态下,操作系统可以访问所有的系统资源和硬件设备,并且可以执行所有的核心功能。
用户态和内核态之间的切换是通过系统调用、异常和外围设备中断来实现的。当应用程序需要访问受限制的系统资源或执行核心功能时,它会发起一个系统调用,这时操作系统会将应用程序的状态切换到内核态,执行相应的操作,然后将状态切换回用户态,继续执行应用程序。
用户态和内核态之间的切换是有开销的,因为需要保存和恢复现场、复制参数和代码等操作。这也是为什么说用户态和内核态切换的开销大的原因。
特权指令和非特权指令
在计算机体系结构中,存在两种主要类型的指令:特权指令和非特权指令。它们在处理器的执行权限方面有所区别。
特权指令
特权指令:系统态下运行的指令(相当于系统指令),对内存的访问不受限制,可以访问用户空间和系统空间,不允许应用程序使用。
特权指令是那些需要较高执行权限的指令,通常由操作系统或内核执行。这些指令涉及到对系统资源的管理和控制,如内存管理、I/O 操作、中断处理等。只有在特殊的特权级别下才能执行这些指令,一般用户程序无法直接执行它们。这有助于确保系统的安全性和稳定性。
常见的特权指令包括:
1. 操作系统调用指令
2. 修改页表的指令
3. 中断和异常处理指令
4. I/O 操作相关指令
5. 修改控制寄存器的指令
非特权指令
非特权指令:在用户态运行的指令,应用程序所使用的所有指令,访问内存受限,只允许访问用户空间,不能对系统中的软件和硬件直接访问。
非特权指令是那些可以由普通用户程序直接执行的指令。它们通常涉及到一般的计算、数据传输和逻辑运算等基本操作。非特权指令执行时不会对系统的关键资源产生直接影响,因此可以由用户程序自由使用。
常见的非特权指令包括:
1. 数据移动指令(如MOV)
2. 算术运算指令(如ADD、SUB)
3. 逻辑运算指令(如AND、OR)
4. 条件分支指令(如JUMP)
5. 栈操作指令(如PUSH、POP)
通过将特权指令和非特权指令分开,计算机体系结构可以实现更好的安全性和系统稳定性,确保只有授权的代码可以执行对系统关键资源的敏感操作。
(二)、进程创建
在系统中,只有进程才能得到运行。因此,程序要想运行,就必须为之创建进程。进程运行结束,还必须撤销它。
(1)用户登录:在分时系统中,用户键入登录命令后,如果是合法用户,系统将为该终端用户建立一个进程,并把它放入就绪队列。
(2)作业调度:在批处理系统中,当作业调度程序调度某个作业时,便将该作业装入主存,为其分配必要的资源,并为之创建进程,放入就绪队列。
(3)提供服务:当运行中的用户进程提出某种请求后,系统将专门创建一个进程来提供用户所需要的服务。
(4)应用请求:基于应用进程自己的需要,由它自己创建一个新进程,这个新进程也称为该进程的子进程。
进程创建的处理过程
一旦操作系统发现了要求创建进程的事件后,便调用进程创建原语,按照下列步骤创建一个新进程:
① 为新进程分配唯一的进程标识符,并从PCB队列中申请一个空闲的PCB。
② 为新进程的程序和数据,以及用户栈分配相应的主存空间及其他必要的资源。
③ 初始化PCB中的相应信息,如标识信息、处理器信息、进程控制信息等。
④ 如果就绪队列可以接纳新进程,便将新进程加入到就绪队列中。
(三)、进程撤销
(1)进程正常结束 这是指程序运行到最后一条指令后。如在C语言程序的函数调用中,执行函数调用的最后一条指令return后,结束该函数。
(2)进程异常错误 在进程运行期间,由于出现某些错误和故障而使进程被迫中止。例如越界错误、超时故障、非法指令错、运行超时、等待超时、算术运算错、I/O故障等。
(3)进程应外界的请求而终止运行 例如,操作员或操作系统要求父进程干预或父进程结束等。
进程撤销的处理过程, 一旦操作系统发现了要求终止进程的事件后,便调用进程终止原语,按照下列步骤终止指定的进程:
① 根据被终止进程的标识符,从PCB集合中检索该进程的PCB,读出进程状态。
② 若该进程处于运行状态,则立即终止该进程的运行。
③ 若该进程有子孙进程,还要将其子孙进程终止。
④ 将该进程所占用的资源回收,归还给父进程或操作系统。
⑤ 将被终止进程的PCB从所在队列中移出,撤销该进程的PCB,并将其加入到空闲的PCB队列中。
(四)、进程等待(进程阻塞)
(1)请求系统服务 正在运行的进程请求系统提供服务时,例如申请打印机打印,但申请服务资源被另外的进程占有,该进程只能处于等待状态。
(2)启动某种操作 正在运行的进程启动某种操作后,其后续命令必须在该操作完成后才能运行,所以要先等待该进程。
(3)新数据尚未到达 对于相互合作的进程,如果一个进程需要先获得另一个进程提供的数据后才能运行,则只有等待所需要的数据到达。
(4)无新工作可做 系统往往设置一些具有特定功能的系统进程,每当这种进程完成任务后,便把自己阻塞起来等待新任务的到来。
进程等待的处理过程, 一旦操作系统发现了要求等待进程的事件后,便调用进程等待原语,按照下列步骤阻塞指定的进程:
① 立即停止执行该进程。
② 修改进程控制块中的相关信息。把进程控制块中的运行状态由“运行”状态改为“等待”状态,并填入等待的原因,以及进程的各种状态信息。
③ 把进程控制块插入到等待队列。根据等待队列的组织方式,把等待进程的进程控制块插入等待队列中。
④ 转调度程序重新调度,运行就绪队列中的其他进程。
(五)、进程唤醒
(1)请求系统服务得到满足 因请求服务得不到满足的等待队列中的进程,得到相应的服务要求时,处于等待队列中的进程就被唤醒。
(2)启动某种操作完成 处于等待某种操作完成的等待队列中的进程,其等待的操作已经完成,可以执行其后续命令,则必须把它唤醒。
(3)新数据已经到达 对于相互合作的进程,如果一个进程需要另一个进程提供的数据已经到达,则把因此而处于等待的进程唤醒。
(4)有新工作可做 系统中的具有特定功能的系统进程,接收到新的任务时,就必须唤醒它。
进程唤醒的过程 , 一旦操作系统发现了要求唤醒进程的事件后,便调用进程唤醒原语,按照下列步骤唤醒指定的进程。
① 从等待队列中找到该进程。
② 修改该进程控制块中的相关内容,把等待状态改为就绪状态,删除等待原语等。
③ 把进程控制块插入到就绪队列中。按照就绪队列的组织方式,把被唤醒的进程的进程控制块插入到就绪队列中。
四、进程同步
对于相关进程间的同步和互斥,必须进行有效的控制。这种控制涉及几个基本概念,即临界资源、临界区、进程同步和进程互斥。
(一)进程同步的概念
1. 临界资源
在系统中有许多硬件或软件资源,如打印机、公共变量等,这些资源在一段时间内只允许一个进程访问或使用,这种资源称为临界资源。
2. 临界区
作为临界资源,不论是硬件临界资源,还是软件临界资源,多个并发进程都必须互斥地访问或使用,这时把每个进程中访问临界资源的那段代码称为临界区。而这些并发进程中涉及临界资源访问的那些程序段称为相关临界区。
在临界区之前增加一段用于检查的代码,这段代码称为进入区。相应地,在临界区后面也要加入一段代码,称为退出区,用于将临界资源的被访问标志恢复为未被访问标志。
3. 进程同步
进程同步是指多个相关进程在执行次序上的协调,这些进程相互合作,在一些关键点上需要相互等待或相互通信。通过临界区可以协调进程间相互合作的关系,这就是进程同步。
4. 进程互斥
进程互斥是指当一个进程进入临界区使用临界资源时,另一个进程必须等待。当占用临界资源的进程退出临界区后,另一个进程才被允许使用临界资源。通过临界区协调进程间资源共享的关系,就是进程互斥。进程互斥是同步的一种特例。
(二)、进程同步机制应遵循的原则
为了实现进程的同步与互斥,可以利用软件方法,也可以在系统中设置专门的同步机制来协调各个进程。但是,所有的同步机制都必须遵循以下四条原则。
空闲让进:当无进程处于临界区时,临界资源处于空闲状态,可以允许一个请求进入临界区的进程进入自己的临界区,有效地使用临界资源。
忙则等待:已有进程进入自己的临界区时,意味着临界资源正被访问,因而其他试图进入临界区的进程必须等待,以保证进程互斥地使用临界资源。
有限等待: 对要求访问临界资源的进程,应保证该进程在有效的时间内进入自己的临界区,以免陷入“死等”状态。
让权等待:当进程不能进入自己的临界区时,应立即释放处理器,以免陷入“忙等”。
(三)、进程同步机制——锁
- 锁的概念
在同步机制中,常用一个变量来代表临界资源的状态,称它为锁。通常用“0”表示资源可用,相当于锁打开。用“1”表示资源已被占用,相当于锁闭合。
互斥锁:最简单的一种线程同步方法,会阻塞线程;
自旋锁:避免切换的一种线程同步方法,属于“忙等待” ;
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
**: 对要求访问临界资源的进程,应保证该进程在有效的时间内进入自己的临界区,以免陷入“死等”状态。
- 让权等待:当进程不能进入自己的临界区时,应立即释放处理器,以免陷入“忙等”。
(三)、进程同步机制——锁
- 锁的概念
在同步机制中,常用一个变量来代表临界资源的状态,称它为锁。通常用“0”表示资源可用,相当于锁打开。用“1”表示资源已被占用,相当于锁闭合。
互斥锁:最简单的一种线程同步方法,会阻塞线程;
自旋锁:避免切换的一种线程同步方法,属于“忙等待” ;
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
[外链图片转存中…(img-mHraF7Il-1715659621307)]
[外链图片转存中…(img-6KXFOzgA-1715659621307)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新