操作系统第二章:进程与线程

进程

包含PCB,程序段,内存

包含五个状态:

  • 创建态
  • 就绪态:等待CPU
  • 运行态
  • 阻塞态:等待其他资源
  • 结束态

进程控制

原语是特殊的程序,执行必须一气呵成,不可中断,通过原语实现进程控制

具有关中断和开中断指令,在这个范围内不会去看是否有中断指令

进程创建

原语内容:

  • 申请空白PCB
  • 为新进程分配所需资源
  • 初始化PCB
  • 将PCB插入就绪队列

进程撤销

原语内容:

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

进程的阻塞和唤醒

阻塞:

  • 找到要阻塞进程的PCB
  • 保护进程运行现场,将PCB状态信息设置为阻塞态,暂时停止进程运行
  • 将PCB插入相应事件的等待队列

唤醒:

  • 在事件等待队列种找到PCB
  • 将PCB从等待队列移除,设置进程为就绪态
  • 将PCB插入就绪队列,等待被调度

进程的切换

  • 将运行环境信息存入PCB
  • PCB移入相应队列
  • 选择另一个进程执行,并更新其PCB
  • 根据PCB恢复新进程所需的运行环境

进程通信

共享存储

    申请共享存储区/数据结构,可以被其他进程所共享,但各个进程对共享空间的访问是互斥的,由进程本身的PV操作来实现。

    分为基于存储区的共享和基于数据结构的共享

消息传递

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

    消息由消息头和消息体构成,消息头包括发送进程ID、接受进程的ID、消息长度等格式化信息

    分为直接通信方式和间接通信方式,间接通信方式即通过信箱进行传递

管道通信

    管道是一个特殊的共享文件(pipe),再内存中开辟了一个大小固定的内存缓冲区,是一个循环队列

    单个管道只能单向传输,称为半双工通信,两个管道可实现双向通信,称为全双工通信

    互斥由操作系统来进行,只要管道没写满就可以往里面写,只要没读完就可以继续读取,读取看作出队

信号

    用于通知进程某个特定事件已经发生,进程收到一个新号后,对该信号进行处理

信号的发送与保存

信号的发送

    信号处理时机

信号处理时机

线程

    是基本的CPU的执行单元,是程序执行流的最小单位

    进程是资源分配的基本单位,线程是调度的基本单位

线程控制块TCB

线程的实现方式

    只有内核级线程才是处理机的分配单位

用户级线程

    应用程序创建线程库来管理各个线程,切换在用户态当中进行即可,不需要切换到内核态,不需要CPU变态,但是一个进程阻塞,其他线程也会被阻塞

用户级线程

内核级线程

    一个被阻塞,其他的还能正常运行,多核的情况下可以将不同进程分派到不同核心进运行

    线程切换需要操作系统来实现,先要用户->内核,再切换内核级线程,再从内核->用户,运行用户级线程切换成本高

内核级线程

多线程模型

  • 一对一:一个用户级线程对应一个内核级线程,开销大,不会阻塞
  • 多对一:多个用户级线程对应一个内核级线程,就相当于一个内核级线程管理线程库
  • 多对多:将n个用户级线程映射到m个内核级线程,每个内核级线程有n个用户级线程,就是多对一的批量版,不会阻塞

线程状态转化

分为:就绪,阻塞,运行

线程控制块(TCB)

TCB

调度

三层调度

高级/作业调度:

高级调度

中级/内存调度:

中级调度

挂起可分为就绪挂起、阻塞挂起

低级/进程/处理机调度

低级调度

进程调度时机

进程调度时机

进程调度方式
  • 非剥夺式调度/非抢占式调度,只允许进程主动放弃处理机
  • 剥夺式调度/抢占式调度,可以强制停止正在执行的进程,将处理机分配给更重要紧迫的进程

    包含选择一个进程和进程切换两个步骤

进程切换完成了

  • 对原来运行进程各种数据的保存
  • 对新的进程各种数据的恢复

调度指标

CPU利用率

    CPU忙碌的时间,$利用率=\frac{忙碌时间}{总时间}$,其他设备的利用率也是如此

系统吞吐量

    单位时间内完成作业的数量,$系统吞吐量=\frac{总共完成的作业数}{总共花费的时间}$

周转时间

    作业被提交给系统开始,到作业完成的时间

具体包含

  • 作业再外存等待作业调度的时间
  • 进程再就绪队列上等待进程调度的时间,就绪
  • 进程再CPU上执行的时间,运行
  • 进程等待I/O操作完成的时间,阻塞

$平均周转时间=\frac{各作业周转时间之和}{作业数}$

$带权周转时间=\frac{作业周转时间}{作业实际运行时间}$

$平均带权周转时间=\frac{各作业带权周转时间之和}{作业数}$

等待时间

    进程/作业等待处理机状态时间之和,对进程来说就是一开始就绪队列等待的时间,对于作业来说还要加上在作业后备队列的等待时间

$平均等待时间=\frac{各作业/进程等待时间}{作业/进程数}$

响应时间

    从用户提交到首次产生响应所用的时间

调度算法

先来先服务(FCFS)

    按照作业/进程到达的先后顺序进行服务,作业按到达后备队列的顺序,进程按到达就绪队列的顺序

    为非抢占式算法,公平,但是短作业的等待时间可能过长,不会导致饥饿(长期得不到服务)

短作业优先(SJF)

    最短的作业和进程优先得到服务,用于进程调度时是短进程优先算法(SPF)

    默认为非抢占式,也有抢占式的版本:最短剩余时间优先算法(SRTN)

    “最短的”平均等待时间,,平均周转时间,平均带权周转时间,但是对长作业不利,可能导致饥饿现象

短作业优先

高响应比优先(HRRN)

    同时考虑到等待和要求服务的时间,$响应比=\frac{等待时间+要求服务时间}{要求服务时间}$,计算当前时刻的响应比,让最大的上

    非抢占式,整合了先来先服务和短作业优先的优点,适用于早期的批处理系统

若要求服务时间相同,则相当于先来先服务,若等待时间相同,就是短作业优先

时间片轮转调度算法(RR)

    按照各进程到达就绪队列的顺序,轮流让各个进程执行一个时间片,分时系统用于进程调度

    抢占式算法,公平,响应快,适用于分时系统,高频的切换有一定的开销且不区分任务紧急程度,不会导致饥饿

默认先到达的进程先插入就绪队列,然后再是又阻塞转为就绪的,或者运行转为就绪的

时间片要让千幻进程的开销占比不超过1%

在分时操作系统当中更注重于响应时间,而不是周转时间

优先级调度算法

    调度时选择优先级最高的作业/进程,优先级是否发生改变可分为动态优先级和静态优先级

    抢占式和非抢占式都有,可以灵活区分优先级,但是如果一直有高优先级进来会导致饥饿

多级反馈队列调度算法

  • 设计多级就绪队列,各个队列时间片从小到大,从第一级开始处理
  • 新进程到达后进入第一级队列队尾,按照先来先服务等待分配时间片,若一次未结束则进入下一级队列队尾,若已经在最后一级,则放到这一级的末尾
  • 在运行当中有更高优先级的到达则会被抢占,被抢占的会放到本级队尾

    用于进程调度,抢占式算法,一直有进程进来会导致饥饿

多级队列调度算法

设置多个队列,不同进程插入对应队列,可采取固定优先级或时间片划分

  • 高优先级空时低优先级进程才能被调度
  • 给不同队列的时间片划分不同

各个队列里可以采用不同的调度策略

多处理机调度

多处理机——多核CPU

负载均衡:尽可能让每一个CPU都同等忙碌

处理机亲和性:尽可能让一个进程调度到同一CPU上运行

通过公共就绪队列,私有就绪队列实现

公共就绪队列

所有CPU共享一个就绪进程队列(位于内核区)

每个CPU调度的时候从这个队列里取,调用后上锁保证互斥访问

天然实现负载均衡,但是各个进程频繁切换CPU运行

私有就绪队列

每个CPU都有一个私有就绪队列

推迁移策略:一个特定的系统程序周期性检查每个处理器的负载,负载不平衡时候从繁忙的队列调到空闲队列

拉迁移:每个CPU运行调度程序时,周期性检查自身负载与其他CPU负载,其他的忙,自己闲则会拉一些过来

同步与互斥


操作系统第二章:进程与线程
http://2819461143wp.github.io/操作系统第二章/
作者
cwdp.sky
发布于
2025年9月22日
许可协议