操作系统基础

操作系统的概念
操作系统(Operating System,OS)是指控制和管理整个计算机系统的硬件和软件资源,并合理地组织调度计算机的工作和资源的分配;以提供给用户和其他软件方便的接口和环境;它是计算机系统中最基本的系统软件。

  • 操作系统是系统资源的管理者
  • 是最接近硬件的一层软件
  • 向上层提供方便易用的服务

image

操作系统的特征 --- 并发

并发:指两个或多个事件在同一时间间隔内发生。这些事件宏观上是同时发生的,但微观上是交替发生的
操作系统的并发性指计算机系统中“同时”运行着多个程序,这些程序宏观上看是同时运行着的,而微观
上看是交替运行的。

单核CPU同一时刻只能执行一个程序,各个程序只能并发地执行。

一个核可以简单认为是一个处理机。

并行

多核CPU同一时刻可以同时执行多个程序,多个程序可以并行地执行。比如Intel的第八代i3处理器就是4核CPU,意味着可以并行地执行4个程序

操作系统的特征 一一 共享

操作系统的特征 一一 虚拟化

2 进程

程序:是静态的,就是个存放在磁盘里的可执行文件,就是一系列的指令集合。
进程(Process):是动态的,是程序的一次执行过程。同一个程序多次执行会对应多个进程。

2.1 PCB

一个程序开始运行前,需要创建对应的进程,要创建相应的PCB,(ProcessControl Block)中,即进程控制块,里面包含进程的多个信息,
比如:
PID,进程ID,一个唯一的PID(Process ID);

进程所属用户ID(UID);

记录给进程分配了哪些资源(如:分配了多少内存、正在使用哪些/O设备、正在使用哪些文件);

记录进程的运行情况(如:CPU使用时间、磁盘使用情况、网络流量使用情况等),可用于实现操作系统对进程的控制、调度;

处理机相关信息,如PSW、PC等等各种寄存器的值(用于实现进程切换);

当进程结束时,会回收其PCB。

2.2

一个进程实体(进程映像)由PCB、程序段、数据段组成。进程是动态的,进程实体(进程映像)是静态的,进程映像可以理解成运行过程中某个时刻的快照,即进程实体反应了进程在某一时刻的状态(如:X++后,x=2)。

程序段:程序的代码(指令序列)
数据段:运行过程中产生的各种数据(如:程序中定义的变量)
image

进程的状态

pcb中有变量表示进程当前所处的状态。
创建态:进程正在被创建时,在这个阶段操作系统会为进程分配资源、初始化PCB。
就绪态:当进程创建完成后,便进入“就绪态”,处于就绪态的进程已经具备运行条件,但由于没有空闲CPU,就暂时不能运行。
运行态:当CPU空闲时,操作系统,就会选择一个就绪进程,让它上处理机运行。
阻塞态:在进程运行的过程中,可能会请求等待某个事件的发生(如等待某种系统资源的分配,或者等待其他进程的响应)。在这个事件发生之前,进程无法继续往下执行,此时操作系统会让这个进程下CPU,并让它进入“阻塞态”。
终止态:一个进程可以执行exit系统调用,请求操作系统终止该进程。此时该进程会进入“终止态”,操作系统会让该进程下CPU,并回收内存空间等资源,最后还要回收该进程的PCB。

进程的转换

image

进程的组织 ---- 链接方式

image

进程的控制

进程控制的主要功能是对系统中的所有进程实施有效的管理,如创建新进程、撤销已有进程、实现进程状态转换等。进程的控制必须是原子的,可以使用原语,因为原语是原子的。
image
例如下面的图示,进程2从阻塞转为就绪,至少有两步,第一,state由2变为1,第二,从阻塞链表到就绪链表上,这两步必须是原子的。
image
image

原语是原子的。可以用“关中断指令”和“开中断指令”这两个特权指令实现原子性。

CPU执行了关中断指令之后,就不再例行检查中断信号,直到执行开中断指令之后才会恢复检查。这样,关中断、开中断之间的这些指令序列就是不可被中断的,这就实现了“原子性”
image

创建原语

申请空白PCB;为新进程分配所需资源,如内存;初始化PCB,如建立PID和UID;将PCB插入就绪队列,进程从创建态转为就绪态。

触发场景

  • 用户登录:分时系统中,用户登录成功,系统会建立为其建立一个新的进程,比如创建一个与用户有关的管理进程或者是通信进程。
  • 作业调度:多道批处理系统中,有新的作业放入内存时,会为其建立一个新的进程。作业:在外存中还未放到内存的程序。作业调度就是把程序放到内存转为进程。
  • 提供服务:用户向操作系统提出某些请求时,会新建一个进程处理该请求
  • 应用请求:由用户进程主动请求创建一个子进程

撤销原语

就绪态/阻塞态/运行态→终止态→无,从PCB集合中找到终止进程的PCB,若进程正在运行,立即剥夺CPU,将CPU分配给其他进程,终止其所有子进程,将该进程拥有的所有资源归还给父进程或操作系统,删除PCB

触发场景

  • 正常结束,进程自己请求终止(exit系统调用)
  • 异常结束,整数除以0、非法使用特权指令,然后被操作系统强行干掉
  • 外界干预,Ctrl+Alt+delete,用户选择干掉进程

阻塞和唤醒

阻塞原语和唤醒原语必须成对使用,即阻塞了某某进程,在之后就要唤醒该进程。

阻塞原语

运行态→阻塞态,找到要阻塞的进程对应的PCB,保护进程运行现场,将PCB状态信息设置为“阻塞态”,暂时停止进程运行,将PCB插入相应事件的等待队列,这会导致进程下处理机。

触发事件

  • 需要等待系统分配某种资源
  • 需要等待相互合作的其他进程完成工作

唤醒原语

运行态→阻塞态,在事件等待队列中找到PCB,将PCB从等待队列移除,设置进程为就绪态,将PCB插入就绪队列,等待被调度
触发事件
等待的事件发生(因何事阻塞,就应由何事唤醒)

切换原语

运行态→就绪态、就绪态→运行态,将运行环境信息存入PCB,PCB移入相应队列,选择另一个进程执行,并更新其PCB,根据PCB恢复新进程所需的运行环境
触发事件

  • 当前进程时间片到
  • 有更高优先级的进程到达
  • 当前进程主动阻塞
  • 当前进程终止

进程通信

进程间通信(Inter-ProcessCommunication,IPC)是指两个进程之间产生数据交互。

进程通信的方式:共享存储、消息传递、管道通信

共享存储

分两种

一.基于存储区的共享

操作系统在内存中划出一块共享存储区,数据的形式、存放位置都由通信进程控制,而不是操作系统。这种共享方式速度很快,是一种高级通信方式。

进程P在公共内存区(没人用的)申请一片内存,先往里写数据,然后进程Q从那读数据。
image

linux中实现共享内存的方式
int shm_open(…);//通过shm_open系统调用,申请一片共享内存区
void * mmap (…);//通过mmap系统调用,将共享内存区映射到进程自己的地址空间

P调用shm_open申请共享内存,然后P和Q都要调用mmap。为避免出错,各个进程对共享空间的访问是互斥的,即P在写,Q就不能写(疑问,能读吗?)。各个进程可使用操作系统内核提供的同步互斥工具(如P、V操作)

二.基于数据结构的共享

比如共享空间里只能放个长度为10的数组。这种共享方式速度慢、限制多,是一种低级通信方式

如下图所示,划分一个长度3的int数组,相当于全局变量,进程P和进程Q往里读写。
image

消息传递

进程间的数据交换以格式化的消息(Message)为单位。进程通过操作系统提供的“发送消息”、“接收消息”两个原语进行数据交换。

格式化的消息即含消息头、消息体的消息。消息头包括:发送进程ID、接受进程ID、消息长度等格式化的信息;消息体即要发送的数据。
image

分为直接通信和间接通信。直接通信方式指,消息发送进程要指明接收进程的ID,间接通信方式指,通过“信箱”间接地通信。因此又称“信箱通信方式”

直接通信

举例说明,操作系统内核中有进程Q的PCB,Q的PCB里有消息队列,进程P使用发送原语给Q发消息,要指明给Q,然后操作系统讲消息挂到进程Q的PCB的消息队列上,进程Q使用接收原语,接收P的消息,要指明接收P,接着系统便会检查队列上是否有P的消息,最后操作系统会把消息体复制到Q的地址空间。
image

image

间接通信

间接通信方式,以“信箱”作为中间实体进行消息传递。

举例说明,内存里有多个信箱,P往信箱A发送消息,Q要拿信箱A里的消息,操作系统就把消息给Q
image

image

可以多个进程往同一个信箱send消息,也可以多个进程从同一个信箱中receive消息。

管道通信

“管道”是一个特殊的共享文件,又名pipe文件。其实就是在内存中开辟一个大小固定的内存缓冲区,本质是是一个环形队列,遵循FIFO,即先进先出。

下图为简易图
image

下图为环形示意图
image

管道只能采用半双工通信,某一时间段内只能实现单向的传输。上面的简易图中,Q也可以写,P也可以读。

如果要实现双向同时通信,则需要设置两个管道。
image

各进程要互斥地访问管道(由操作系统实现)

当管道写满时,写进程将阻塞,直到读进程将管道中的数据取走,即可唤醒写进程。

当管道读空时,读进程将阻塞,直到写进程往管道中写入数据,即可唤醒读进程。

管道中的数据一旦被读出,就彻底消失。因此,当多个进程读同一个管道时,可能会错乱。对此,通常有两种解决方案:一个管道允许多个写进程,一个读进程。允许有多个写进程,多个读进程,但系统会让各个读进程轮流从管道中读数据(Linux的方案)。

信号

用于通知进程某个特定事件已经发生。进程收到一个信号后,对该信号进行处理。是为了实现进程间的通信。

linux系统的信号举例

序号 信号名 信号对应的事件 默认处理事件
2 SIGINT 来自键盘的中断(Control-C) 终止
8 SIGFPE 浮点异常(如:除以0) 终止并转储内存
9 SIGKILL 杀死进程(如:父进程杀子进程) 终止
28 SIGWINCH 窗口大小变化 忽略

原理

进程的PCB中有两个位向量,用来记录要处理的信号和屏蔽的信号,0是false,1是true,置1表示要处理该类型的事件
image

  • 上图示例中有八位,表示支持八类信号

常用的系统调用函数,用来发送信号给进程,pid是进程ID,sig是信号类型
int kill(pid_t pid , int sig)

现在有进程2、进程3、OS内核进程,调用kill,进程1的pid是2066
进程2调用,kill(2066,1);
进程3调用,kill(2066,8);
内核进程调用,kill(2066,1);

进程1的PCB里的两个信号位向量变成下图,信号类型1置为1,8置为1,由于8被阻塞,所以8不用处理,只有1要处理。注意,进程2和内核进程都是kill(2066,1),重复收到的同类信号,将丢弃,所以进程1是无法区分是哪个进程发送过来的信号类型1。
image

每种信号对应一个默认处理事件,默认处理事件是系统默认设置的,各个进程可以自定义自己的处理事件。

当进程从内核态转为用户态时(如:系统调用返回、或中断处理返回时),例行检查是否有待处理信号,如果有,就处理信号。

例如一,进程执行了trap,陷入内核态
image

例如二,IO中断
image

运行信号处理程序后会继续执行进程的下一条指令,除非处理程序将进程阻塞或终止了,并且将pending位重置为0,比如将上面位置1置为0。

当同时收到多个不同类信号时,通常先处理序号更小的信号。比如pending位有1、2、5、8,优先处理1

信号与异常

线程

有的进程可能需要“同时”做很多事,而传统的进程只能串行地执行一系列程序。为此,引入了“线程”,来增加并发度。
image
image

传统进程机制中,进程是资源分配、调度的基本单位;引入线程后,进程是资源分配的基本单位,线程是调度的基本单位。

传统进程机制中,只能进程间并发;引入线程后,各线程间也能并发,提升了并发度。

传统的进程间并发,需要切换进程的运行环境,系统开销很大;线程间并发,如果是同一进程内的线程切换,则不需要切换进程环境,系统开销小;引入线程后,并发所带来的系统开销减小

内核级线程

内核级线程,Kernel-Level Thread,KLT,又称“内核支持的线程”
image

内核级线程是基本的调度单位,进程作为资源分配的基本单位。
操作系统只“看得见”内核级线程,操作系统在分配处理机资源时,是以内核级线程为单位的。

用户级线程是“代码逻辑”的载体
内核级线程是“运行机会”的载体

不同的内核级线程可以跑不同的代码逻辑。比如上图中,左边的跑文字聊天,中间的跑视频聊天,右边跑文件传输。

多线程模型

一对一

一对一模型:一个用户级线程映射到一个内核级线程。每个用户进程有与用户级线程同数量的内核级线程。

优点:当一个线程被阻塞后,别的线程还可以继续执行,并发能力强。多线程可在多核处理机上并行执行。

缺点:一个用户进程会占用多个内核级线程,线程切换由操作系统内核完成,需要切换到核心态,因此线程管理的成本高,开销大。
image

多对一

多对一模型:多个用户级线程映射到一个内核级线程。且一个进程只被分配一个内核级线程。

优点:用户级线程的切换在用户空间即可完成,不需要切换到核心态,线程管理的系统开销小,效率高
缺点:当一个用户级线程被阻塞后,整个进程都会被阻塞,并发度不高。多个线程不可在多核处理机上并行运行
image

多对多

多对多模型:n用户及线程映射到m个内核级线程(n>=m)。每个用户进程对应m个内核
级线程。
克服了多对一模型并发度不高的缺点(一个阻塞全体阻塞),又克服了一对一模型中一个用户进程占用太多内核级线程,开销太大的缺点。

用户级线程是“代码逻辑”的载体
内核级线程是“运行机会”的载体
image

内核级线程中可以运行任意一个有映射关系的用户级线程代码

举例说明映射,在上图中,当视频聊天比较耗费CPU资源时,可以让视频聊天线程映射到左边的内核级线程,让文字聊天和文件传输映射到右边的内核级线程;然后过一段时间,当文件传输比较耗费CPU资源时,可以让文件传输线程映射到左边的内核级线程,让文字聊天和视频聊天映射到右边的内核级线程。可以由线程库来改变映射。

只有两个内核级线程中正在运行的代码逻辑都阻塞时,这个进程才会阻塞。

调度

高级调度

又称作业调度,作业,即一个具体的任务,用户向系统提交一个作业,大概就是用户让操作系统启动一个程序,来处理一个具体的任务。高级调度,即按一定的原则从外存的作业后备队列中挑选一个作业调入内存,并创建进程。每个作业只调入一次,调出一次。作业调入时会建立PCB,调出时才撤销PCB,调出即完成。
大意是,用户双击了好些个程序,然后内存有时会不足,操作系统需要看下先启动哪个,然后接着启动哪个,接着启动哪个。
image

低级调度

低级调度,又称进程调度、处理机调度,即,按照某种策略(算法)从就绪队列中选取一个进程,将处理机分配给它。
进程调度的频率很高,一般几十毫秒一次。

大意是,内存里有很多作业,处理器的核心就那么几个(甚至一个),操作系统要按照某某策略从就绪队列里选作业到处理机上运行。
image

中级调度

内存不够时,可将某些进程的数据调出外存。等内存空闲或者进程需要运行时再重新调入内存。暂时调到外存等待的进程状态为挂起状态。
被挂起的进程PCB会被组织成挂起队列。
中级调度(内存调度)一一按照某种策略决定将哪个处于挂起状态的进程重新调入内存。
一个进程可能会被多次调出、调入内存,因此中级调度发生的频率要比高级调度更高。
image

七状态模型

暂时调到外存等待的进程状态为挂起状态(挂起态,suspend);
挂起态又可以进一步细分为就绪挂起、阻塞挂起两种状态;

注意“挂起”和“阻塞”的区别,两种状态都是暂时不能获得CPU的服务,但挂起态是将进程映像调到外存去了,而阻塞态下进程映像还在内存中;
有的操作系统会把就绪挂起、阻塞挂起分为两个挂起队列,甚至会根据阻塞原因不同再把阻塞挂起进程进一步细分为多个队列。
image

联系与对比

image

进程调度概览

1.进程调度的时机
2.进程调度时的方式(非剥夺调度方式(非抢占式)与剥夺调度方式(抢占式))
3.进程调度与进程切换的过程
注意,调度的目的是为了进程切换。

进程调度(进程切换)的时机

  1. 当前运行的进程主动放弃处理机
  • 进程正常终止(即完成了,结束了)
  • 运行过程中发生异常而终止
  • 进程主动请求阻塞(如等待I/O)
  1. 当前运行的进程主动放弃处理机
  • 分给进程的时间片用完
  • 有更紧急的事需要处理(如I/O中断)
  • 有更高优先级的进程进入就绪队列

注意:以下情形发生时,不能调度

  • 在处理中断的过程中。中断处理过程复杂,与硬件密切相关,很难做到在中断处理过程中进行进程切换。
  • 进程在操作系统内核程序临界区中。
  • 在原子操作过程中(原语)。

调度器

调度器即调度程序
image

闲逛进程

调度程序永远的备胎,没有其他就绪进程时,运行闲逛进程(idle)

闲逛进程的特性:

  • 优先级最低
  • 可以是0地址指令,占一个完整的指令周期(指令周期末尾例行检查中断)
  • 能耗低

调度算法

有各种算法,要学习体会算法的思想,
是可用于进程调度还是作业调度,还是都可用;
是抢占式还是非抢占式,处理机上的进程主动放弃处理机,才会轮到下个进程上处理机,这就是非抢占式;、
会不会导致饥饿,饥饿就是进程长时间得不到处理机的服务(上不了处理机)

先来先服务

FCFS,按照到达的先后顺序调度。属于非抢占式。不会导致饥饿。

用于作业调度时,考虑的是哪个作业先到达后备队列;用于进程调度时,考虑的是哪个进程先到达就绪队列

示例,调度顺序为:P1→P2→P3→P4
image
image

短作业优先

SJF, Shortest Job First,运行时长最短的作业/进程优先上处理机,每次调度时选择当前已到达且运行时间最短的作业/进程。非抢占式。会导致饥饿。

即可用于作业调度,也可用于进程调度。用于进程调度时,称为“短进程优先(SPF,Shortest ProcessFirst)算法”

示例,调度顺序为:P1→P3→P2→P4

image

image

最短剩余时间优先算法

SRTN,Shortest Remaining Time Next,每当有进程加入就绪队列改变时就需要调度,如果新到达的进程剩余时间比当前运行的进程剩余时间更短,则由新进程抢占处理机,当前运行进程重新回到就绪队列。另外,当一个进程完成时也需要调度,即主动放弃CPU。会导致饥饿。抢占式。
image
当有新进程到达时就绪队列就会改变,就要按照上述规则进行检查。以下P。(m)表示当前P。进程剩余时间为m。各个时刻的情况如下:
0时刻(P1到达): P(7)
2时刻(P2到达): P(5)、P2(4)
4时刻(P3到达): P1(5)、P2(2)、P.(1)
5时刻(P3完成且P4刚好到达):P(5)、P2(2)、P4(4)
7时刻(P2完成): P1(5)、 P4(4)
11时刻(P4完成): P(5)
image

高响应比优先

HRRN,Highest Response Ratio Next,

时间片调度算法

按照各进程到达就绪队列的顺序,轮流让各个进程执行一个时间片(如100ms),先到先执行,若进程未在一个时间片内执行完,则下处理机,将进程重新放到就绪队列的队尾,重新排队,故是抢占式的,若进程在一个时间片内执行完则进行调度,即让队头的进程上处理机;用于进程调度,只有作业放入内存建立了相应的进程后,才能被分配处理机时间片;由时钟装置发出时钟中断来通知CPU时间片已到。

其实就是队列的先进先出,这里是先进先上处理机。

举例1,时间片为2
image
0时刻,只有p1到达,进就绪队列,上处理机
image
2时刻,p1运行了2,下处理机,p2到达,p2排前面,p1排后面,p2上处理机
image
4时刻,p2运行了2,下处理机,p3到达,p2排在p3后,p1上处理机
image
剩余的情况以此类推,下图为运行示意图。
image

非抢占式优先级调度算法

每次调度时选择当前已到达且优先级最高的进程。当前进程主动放弃处理机时发生调度。

举例,优先数大的表示优先级高
image

注:以下括号内表示当前处于就绪队列的进程
0时刻(P1):只有P1到达,P1上处理机。
7时刻(P2、P3、P4):P1运行完成主动放弃处理机,其余进程都已到达,P3优先级最高,P3上处理机。
8时刻(P2、P4):P3完成,P2、P4优先级相同,由于P2先到达,因此P2优先上处理机
12时刻(P4):P2完成,就绪队列只剩P4,P4上处理机。
image

抢占式优先级调度算法

每次调度时选择当前已到达且优先级最高的进程。当前进程主动放弃处理机时发生调度。另外,当就绪队列发生改变时也需要检查是会发生抢占。

示例
image

注:以下括号内表示当前处于就绪队列的进程
0时刻(P1):只有P1到达,P1上处理机。
2时刻(P2):P2到达就绪队列,优先级比P1更高,发生抢占。P1回到就绪队列,P2上处理机。
4时刻(P1、P3):P3到达,优先级比P2更高,P2回到就绪队列,P3抢占处理机。
5时刻(P1、P2、P4):P3完成,主动释放处理机,同时,P4也到达,由于P2比P4更先进入就绪队列,
因此选择P2上处理机
7时刻(P1、P4):P2完成,就绪队列只剩P1、P4,P4上处理机。
11时刻(P1):P4完成,P1上处理机
image

优先级调度算法的补充

image

多级反馈队列调度算法

posted @ 2026-08-26 10:51  dvdhellohaha  阅读(8)  评论(0)    收藏  举报