【操作系统】进程与线程1

进程

程序:静态的,存储于磁盘里的可执行文件,是一系列的指令集合
进程:动态的,程序的一次执行过程。进程实体=PCB+程序段+数据段。进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位。
进程控制块(Process Control Block PCB):是进程存在的唯一标志。保存进程描述信息,进程控制和管理信息,资源分配清单,处理机相关信息

进程的特征
  • 动态性
  • 并发性
  • 独立性:进程是能独立运行、独立获得资源、独立接受调度的基本单位
  • 异步性:各进程以不可预知的速度向前推进,可能导致运行结果的不确定性
  • 结构性
进程状态

就绪态:操作系统为进程分配资源、初始化PCB,完成创建,等待CPU执行进程
运行态:进程此时在CPU上运行
阻塞态:进程运行时,请求等待某个事件发生,进程无法继续执行,进入阻塞态
终止态:进程执行exit系统调用,操作系统回收内存资源,最后回收PCB
fivestates
进程的状态转换过程需要用原语实现。
进程控制相关原语:

  • 创建原语:创建态->就绪态。申请空白PCB、为新进程分配所需资源、初始化PCB、将PCB插入就绪队列
  • 撤销原语:某种状态->终止态。从PCB集合找到终止进程的PCB,终止其所有子进程,归还资源,删除PCB
  • 阻塞原语:运行态->阻塞态。找到阻塞的PCB,保护进程运行现场,将PCB插入相应事件的等待队列
  • 唤醒原语:阻塞态->就绪态。找到等待队列的PCB,将其从队列移除,设置进程为就绪态,插入就绪队列
  • 切换原语:运行态->就绪态,就绪态->运行态。将运行环境(寄存器信息)存入PCB,PCB移入相应队列;选择进程执行,更新PCB,根据PCB恢复新进程所需运行环境
进程通信

进程间通信:Inter-Process Communication IPC,指两个进程间的信息交互。
方法一:实现共享存储区
为避免出错,各个进程对共享空间的访问互斥
基于存储区的共享:OS在内存中划出一块共享存储区。数据的形式、存放位置由通信进程控制。速度很快。
基于数据结构的共享:共享空间中只能放特定的数据形式,速度慢,限制多,是一种低级通信方式。
方法二:消息传递
进程间的数据交换以格式化的消息为单位,进程通过OS提供的”发送消息/接收消息“原语进行数据交换。
直接通信方式:发送方指明接收进程ID
间接通信方式:以”信箱“作为中间实体进行消息传递。
方法三:管道通信
”管道“是一个特殊的共享文件,又名pipe文件。实质是在内存中开辟一个大小固定的循环队列式内存缓冲区。先写后读。
一个管道只能采用半双工通信,如果要实现双向同时通信,则需要设置两个管道。
各进程要互斥访问管道
当管道写满时,写进程阻塞。当管道为空时,读进程阻塞。
为避免多个进程同时读同一个管道时,数据错乱:一个管道允许多个写进程,一个读进程;或通过OS控制多个读进程有序读数据。

线程

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

  • 各线程之间也能并发,提升了并发度。
  • 每个线程都有一个线程ID、线程控制块TCB。
  • 同一进程的不同线程间共享进程资源。
  • 同一进程内的线程切换,不需要切换进程环境,系统开销小。不同进程的线程切换,会引起进程切换。
线程实现方式

用户级线程:User-Level Thread ULT。早期OS只支持进程,线程是由编程语言提供的线程库实现并管理的。OS意识不到用户级线程的存在。

  • 优:用户级线程的切换在用户空间即可完成,不需要切换到核心态。系统开销小,效率高
  • 缺:当一个线程被阻塞后,整个程序都会被阻塞,并发度不高。
int i=0;
while(true){
	if(i==0) run thread1();
	if(i==1) run thread2();
	if(i==2) run thread3();
	i=(i+1)%3;
}

内核级线程:Kernel-Level Thread KLT。线程的管理工作由OS内核完成。线程的切换必须在核心态下完成。OS为每个线程建立TCB。

  • 优:一个线程被阻塞后,其他线程可继续执行,并发能力强
  • 缺:线程管理成本高,开销大。
多线程模型:

一对一模型:一个用户级线程映射到一个内核级线程(类似纯内核级线程)
多对一模型:多个用户级线程映射到一个内核级线程,且一个进程只被分配一个内核级线程。(类似纯用户级线程)
多对多模型:n用户级线程映射到m个内核级线程(n>=m)。

线程的状态转换

线程状态转换

调度

高级调度:作业调度。按一定原则从外存的作业后备队列中选择一个作业调入内存,并为其创建进程。每个作业只调入一次,作业调入时建立PCB,调出时撤销PCB。外存->内存(面向作业)
中级调度:内存不足时,将某些进程的数据调入外存,等内存空闲或进程需要运行时再重新调入内存。暂时调入外存等待的进程状态为挂起状态。外存->内存(面向进程)
低级调度:进程调度/处理机调度。按某种策略从就绪队列种选择一个进程,将处理机分配给它。内存->CPU
七状态转换

进程调度的时机
  • 当前运行进程主动放弃处理机
    • 进程正常终止
    • 运行过程中发生异常而终止
    • 进程主动请求阻塞
  • 被动放弃
    • 分给进程的时间片用完
    • 有更紧急的事处理
    • 有更高优先级的进程进入就绪队列
      不能进行进程调度与切换的情况
  1. 处理中断的过程中
  2. 进程在OS内核程序临界区
  3. 原子操作过程中

临界资源:一个时间段内只允许一个进程使用的资源,各进程需要互斥访问临界资源。
临界区:访问临界资源的那段代码
内核临界区:用来访问某种内核数据结构的,如不尽快释放,极可能影响到OS内核的其他管理工作。

进程调度方式
  • 非剥夺调度方式:非抢占式,只允许进程阻塞或退出才触发调度程序工作。
    系统开销小,但无法及时处理紧急任务。适用于早期批处理系统
  • 剥夺调度方式:抢占方式,如果有更重要或更迫切的进程需要使用调度机,立即暂停当前正在执行的进程,将处理机分配给后来者进程。
    可以优先处理更紧急的进程,也可以让各进程按照时间片轮流执行(时钟中断控制)。适用于分时、实时操作系统

进程切换:1. 对原来运行进程各种数据进行保存。2. 对新的进程各种数据的恢复。进程的切换是有代价的。
在没有其他就绪进程时,调度程序运行闲逛进程idle。闲逛进程优先级最低。可以是0地址指令,占一个完整指令周期,能耗低。

调度算法评价指标
  • CPU利用率:CPU忙碌时间占总时间的比。
  • 系统吞吐量:单位时间内完成作业的数量。=总共完成多少道作业/完成时间
  • 作业周转时间:作业提交给系统开始,到作业完成为止的时间间隔。=作业完成时间-作业提交时间
  • 平均周转时间=各个作业周转时间之和/作业数
  • 带权周转时间=作业周转时间/作业实际运行的时间

当两个作业的周转时间相同,但一个作业是等待10执行1,而另一个作业时等待1执行10,两者肯定不同。

  • 等待时间:作业/进程处于等待处理机状态时间之和
  • 平均等待时间

进程而言,等待I/O完成的期间也是在被服务,所以不计入等待时间
作业而言,不仅要考虑建立进程后的等待时间,也要加上作业在外存后备队列中的等待时间。

  • 响应时间:用户提出请求到首次产生响应所用的时间

调度算法

以下三种算法可用于作业,也可用于进程调度。

先来先服务FCFS

按照作业/进程到达的先后顺序进行服务
非抢占式算法
pic
周转时间:完成时间-到达时间
P1=7-0=7, P2=11-2=9, P3=12-4=8, P4=16-5=11
带权周转时间:周转时间/运行时间
P1=7/7=1, P2=9/4=2.25, P3=8/1=8, P4=11/4=2.75
等待时间:周转时间-运行时间-I/O操作时间
P1=7-7=0, P2=9-4=5, P3=8-1=7, P4=11-4=7

进程 到达时间 运行时间 周转时间 带权周转时间 等待时间
P1 0 7 7 1 0
P2 2 4 9 2.25 5
P3 4 1 8 8 7
P4 5 4 11 2.75 7

优:公平,算法实现简单
缺:对长作业有利,对短作业不利。比如P3
不会导致饥饿。

短作业优先SJF

当前已到达且最短运行时间的作业/进程优先得到服务。
非抢占式版本
pic

抢占式版本——最短剩余时间优先算法SRTN
每当有进程加入就绪队列,如果新到达的进程剩余时间比当前运行进程剩余时间短,则新进程抢占处理机,当前运行进程重回就绪队列。例子中调度顺序为:P1->P2->P3->P2->P4->P1pic

优:“最短的”平均等待时间、平均周转时间
缺:不公平,对短作业有利,对长作业不利
会导致饥饿

高响应比优先HRRN

在每次调度时先计算各个作业/进程的响应比,选择响应比最高的作业/进程为其服务
\(响应比=\frac{等待时间+运行时间}{运行时间}\)
非抢占式
优:综合考虑了等待时间和运行时间,是上述两种方法的折中
缺:
避免了饥饿

以上三种算法一般适用于早期的批处理系统中,因为这些算法主要关心对用户的公平性、平均周转周期、平均等待时间等评价系统整体性能的指标 ,但不关心响应时间,不区分任务的紧急程度,因此对用户来说交互性很差。


时间片轮转RR(Round-Robin)

进程调度
算法思想:公平、轮流为各个进程服务,让每个进程在一定时间间隔内都可以得到响应。按照各进程到达就绪队列的顺序,轮流让各个进程执行一个时间片,若进程未在一个时间片内执行完,则剥夺处理机,将进程重新放回就绪队列队尾重新排队
抢占式:由时钟装置发出时钟中断通知CPU时间片已到
pic

Tip:如果一个时间片时间到进程A未执行完,且进程B刚到,则默认先到达的进程B先插入就绪队列,然后进程A再插入。

如果时间片太大,使得每个进程都可以在一个时间片内完成。如果时间片太小,则进程切换过于频繁,系统开销增大。
优:公平、响应快,适用于分时操作系统
缺:高频率进程切换,并没有优先级的概念
不会饥饿

优先级调度算法

调度时选择优先级最高的
非抢占式版本:每次调度时选择当前已到达且优先级最高的进程。当前进程主动放弃处理机时发生调度
抢占式版本:当前进程主动放弃处理机,或就绪队列发生改变时需要检查是否会发生抢占
根据优先级是否可以改变:静态优先级,动态优先级

Tips:系统进程高于用户进程。前台进程高于后台进程。OS更偏好I/O型进程

优:用优先级区分紧急程度、重要程度,适用于实时操作系统
缺:若源源不断的高优先级进程,则可能导致饥饿
会饥饿

多级反馈队列调度算法

进程调度

  1. 设置多级就绪队列,各级队列优先级从高到低,时间片从小到大
  2. 新进程到达加入1级队列,按FCFS被分配,若用完时间片进程未结束,则进入下一级队列队尾。若没有下一级则放入本级队尾。
  3. 只有k级队列为空时,才会为k+1级队头进程分配时间片
  4. 在k级队列进程运行过程中,若1~k-1级队列中加入新进程,则新进程会抢占处理机,原来运行的进程放回k级队列队尾
    抢占式
    优:(端水大师)相对公平、新进程可很快得到响应、短进程可用较少的时间完成、可灵活调整对各类进程的偏好程度
    会饥饿

以上三种算法适用于交互式系统。更注重系统的响应时间、公平性、平衡性等指标,能较好地满足交互式系统的需求。

多级队列调度算法

系统中按进程类型设置多个队列,进程创建成功后插入某个队列。
各队列可采用不同的调度算法。队列之间可采取固定优先级或时间片划分不同。

posted @ 2023-05-17 21:07  梅落南山  阅读(14)  评论(0编辑  收藏  举报