进程与线程
- 多道程序设计
- 程序的顺序执行
- 程序的并发执行
- 多道程序设计
- 多道程序设计技术的引入
- 多道程序设计环境的特点
- 多道程序设计的缺陷
- 进程
- 进程的定义
- 进程的状态与转换
- 进程控制块
- PCB的内容
- 进程的组成
- PCB组织
- 进程的队列
- 进程队列的组成
- 进程控制
- 线程
- 线程的基本概念
- 进程和线程
- 线程实现机制
- 用户级线程与内核级的线程的比较
- 进程调度
- 概述
- 调度算法设计原则
- 进程调度算法
- 先来先服务算法
- 最短进程优先算法
- 最短剩余时间优先算法
- 最高响应比优先算法
- 轮转算法
- 最高优先级算法
- 多级反馈队列算法
- 系统内核
多道程序设计
目的:提高处理器与各种资源的利用率。充分发挥了处理器与外围设备以及外围设备之间并行工作的能力,从而提高处理器与其他各种资源的利用率
程序的顺序执行
顺序执行:按照命令顺序依次执行。
- 顺序性:程序和机器执行他的活动严格一一对应。
- 封闭性:计算结果取决于程序自身,程序执行得到的最终结果由给定的初始条件决定,不受外界因素影响。
- 程序执行结果的确定性:处理器在执行程序时,任意两个动作之间的停顿对程序的计算结果不产生影响。
- 程序执行结果的可再现性:只要初始条件相同,无论何时重复执行都得到相同的结果。
程序的并发执行
并发执行:指同一时间有两个或两个以上程序在计算机系统中处于开始执行且尚未结束的状态。
- 执行期间并发程序相互制约:资源的共享和竞争存在于多道程序的并发执行中,从未制约了各道程序的执行速度。
- 程序与计算不再一一对应:在并发执行中,允许多个用户进程调用同一程序段,从而形成多个“计算”。
- 并发程序的执行结果不可再现:并发程序执行结果与其执行的相对速度以及并发执行的多道程序之间的相互关系有关,导致并发执行的程序结果不可再现。
- 程序的并行执行与程序的并发执行:并发执行是指宏观上的,单处理器时微观上程序仍然是顺序执行的,即某一时刻仍只执行一个程序,多个程序快速切换照成同时执行的错觉,多处理时,程序在各自的处理器上运行。并行执行是指不论在宏观还是微观上程序都在同时运行。
多道程序设计
现代操作系统中,为了提高系统中各种资源的利用率,缩短执行的周转时间,广泛使用了多道程序设计技术,使多种硬件资源可以并行工作。
多道程序设计技术的引入
在许多情况下,要求计算机可以同时处理多个具有独立功能的程序,以增强系统的处理能力和提高机器的利用率。通常采用并行操作技术,使系统的各种硬件资源尽量做到并行工作。
此时系统中的软件,硬件资源不再由某一程序独享,而是由几道程序共享。
举例:顺序执行与并发执行资源利用率的差别
程序A执行顺序:CPU:10s、DEV1:5s、CPU:10s、DEV2:10s、CPU:10s。
程序A执行顺序:DEV2:10s、CPU:10s、DEV1:5s、CPU:5s、DEV2:10s。
顺序环境下执行A和B:共80s。其中CPU:40s(利用率:40/80=50%)、DEV1:15s(利用率:15/80=18.75%)、DEV2:25s(利用率:20/80=31.25%)。
并发环境下执行A和B,二者同时执行:共45s。其中CPU:40s(利用率:40/45=89%)、DEV1:15s(利用率:15/45=33%)、DEV2:25s(利用率:20/45=56%)。
由此可见,采用多道程序设计技术执行同样的两个程序,能大大个改进系统性能。
多道程序设计环境的特点
所谓多道程序设计,就是允许多个程序同时进入内存并允许。多道程序设计技术是操作系统所采用的最基本、最重要的技术,目的就是提供整个系统的效率。
衡量系统效率的尺度就是吞吐量,即单位时间内所处理程序的数量(进程的道数)。
特点:
- 独立性:每道程序逻辑上是独立的,且执行速度也与其他程序无关。
- 随机性:多道程序环境下,程序的开始时间与数据的输入都是随机的。
- 资源共享性:一般而言,程序的道数总是多于处理器的数量,因此输入输出设备、内存、信息等资源都将被共享,资源共享将导致对进程执行速度的制约。
多道程序设计的缺陷
- 相对于顺序执行可能延长程序的执行时间。
- 系统效率的提高有一定限度。
进程
并发程序和顺序程序的执行有本质上的差异,为了更好的描述程序的并发执行,实现操作系统的并发性和共享性。
进程的定义
进程是具有一定独立功能的程序在某个数据集合上的一次运行活动,是系统进行资源分配和调度的一个独立单位。
从操作系统角度来看,分为用户进程(用户程序)和系统进程(操作系统程序)。系统进程优先级通常高于用户进程。
进程与程序的关联与区别
- 联系:程序是构成进程的组成部分之一,一个进程的运行目的就是执行它所对应的程序,如果没有程序,进程则将失去意义。从静态角度看,进程由程序、数据、进程控制块三部分组成。
- 区别:程序是静态的,进程是动态的。即进程是程序的一个执行过程。程序是永久存在的,而进程具有生命周期。
一个进程可以包括若干程序的执行,一个程序也可以包含多个进程。比如编译进程由词法分析、语法分析、代码生成和优化等若干程序组成。而一个编译程序有时也同时生成几个进程,同时为多个用户服务。
进程具有创建其他进程的功能,被创建的进程称为子进程的,创建者成为父进程,从而构成进程家族。
可再入程序
一个能够被多个用户同时调用的程序称为可再入程序。即程序功能是不可变的,程序在运行过程中不会修改自身代码(数据与程序相分离)。
进程的特征
使用进程的概念可以很好的描述程序的并发执行,并能够揭示操作系统的内部特性。事实上,操作系统的并发现和共享性正是通过进程来体现的。
进程具有两个基本属性:
- 进程是一个可拥有资源的独立单位。
- 进程又是一个可以独立调度和分派的基本单位。
进程具有以下特性:
- 并发现:一个进程可以与其它进程一同运行。
- 动态性:进程对应着程序的执行过程,动态性体现在两个方面,一是进程具有生命周期,二是运行过程中进程状态一直在改变。
- 独立性:一个进程是一个相对完整的资源分配单位。
- 交往性:一个进程运行过程中可以与其他进程发生直接或间接的相互作用。
- 异步性:每个进程都按照各自独立、不可预知的速度向前推进。
- 结构性:一个进程由程序、数据、进程控制块三部分组成。
进程的状态与转换
进程从创建到结束的过程中一直处于一个状态不断变化的过程。
三状态进程模型
- 运行状态:进程已经获得处理器,并在处理器执行的状态。
- 就绪状态:以做好运行准备,在等待获取处理器。
- 等待状态:也称阻塞或封锁状态,是指进程等待某种事件发生,而暂时不具备可运行的条件。引起等待的事件一旦消失,即进入就绪状态。如等待I/O操作。
状态的转换:
- 就绪 > 运行:就绪状态的程序根据调度算法获取到处理器进行运算。
- 运行 > 就绪:通常出现在分时操作系统中,对处理器的占用时间已经耗尽。
- 运行 > 等待:符合某一阻塞条件。
- 等待 > 就绪:产生阻塞的条件已经解除。
五状态进程模型
- 运行状态:进程已经获得处理器,并在处理器执行的状态。
- 就绪状态:以做好运行准备,在等待获取处理器。
- 等待状态:也称阻塞或封锁状态,是指进程等待某种事件发生,而暂时不具备可运行的条件。引起等待的事件一旦消失,即进入就绪状态。如等待I/O操作。
- 创建状态:进程正在创建过程中,还不可运行。操作系统在此状态分配和建立进程控制块,建立资源表格(如打开文件夹),并分配资源。
- 结束状态:进程以结束运行,回收除进程控制块的其他资源。
七状态进程模型
进程控制块
为了便于系统控制和描述进程的活动过程,在操作系统核心中定义了一个专门的数据结构,称为进程控制块(PCB)。
操作系统用PCB来描述进程的基本状况以及进程的运行变化过程。PCB是进程存在的唯一标志,系统创建进程时,为进程设置一个PCB,在利用PCB对进程加以控制和管理。撤销进程时,系统回收它的PCB,进程随之消亡。
PCB的内容
PCB的内同可分为两部分:
- 调度信息:供进程调度时使用,描述了当前进程所处的状态
- 进程名和进程号:标识一个进程,进程号具有唯一性。
- 地址空间信息:记录系统为进程分配的地址空间的相关信息。
- 优先级:记录进程本身有限级别,共调度时使用。
- 当前状态:指明进程处于哪种状态。
- 资源清单:列出进程运行所需要的资源。
- 家族关系:指明进程是父进程还是子进程。
- 消息队列指针:指明进程所属的消息队列所在地址,消息队列的作用是用于与其他进程通信。
- 进程队列指针:指出进程在队列中的位置。
- 当前打开文件:记录进程正在使用的文件情况。
- 现场信息:刻画了进程的运行状况,记录了可被其他进程改变的信息,如时钟、程序状态字、界地址寄存器。一旦中断进程的运行,必须把上述信息存起来。
PCB的大小随系统不同而异,不仅和系统的管理和控制方法有关,还和系统规模大小有关。
进程的组成
进程由程序、数据、进程控制块组成。
PCB时进程的灵魂,保持着进程的地址信息,通过PCB可以得到进程程序的存储位置,可以找到整个进程。
程序和数据是躯体,程序定义了实现的功能,数据则是程序操作的对象。
PCB组织
为了便于管理,系统把所有PCB用适当的方式组织起来
- 线性方式:将所有PCB信息存在一个表里(PCB表),
- 优点:简单、不需要额外开销,适应进程数目少的系统
- 缺点:需要全表扫描才可找到对应PCB
- 索引方式:在线性方式的基础上,新增不同的PCB索引表,记录状态相同的PCB。
- 链接方式:将具有共同状态的PCB,通过PCB中的链接字构成一个队列。等待队列可以有多个,对应不同的等待原因。
进程的队列
通常分为以下三类
- 就绪队列:进程入队与出队与处理器调度算法有关。
- 等待队列:每个等待事件对应一个等待队列。
- 运行队列:每个处理器对应一个运行队列,实际上一个运行队列中只有一个进程。
进程队列的组成
进程队列的入队与出队与双向链表增删元素思路一致。
进程控制
进程控制就是控制进程生命周期中各种状态的转换。
通过进程控制原语来实现。
进程控制原语:原语是操作系统核心的一个组成部分,是一批连续的指令,具有不可分割性,执行时也不可中断。必须在管态下运行,并且常驻内存。
进程控制原语
线程
人们在进程的基础上,提出了更小、能够独立运行的基本单位:线程。
线程可提高系统内程序并发执行的级别,可以进一步提高系统效率。
线程的基本概念
操作系统引入进程的目的是为了使多个程序并发执行,以改善资源利用率及提高系统运行效率,那么引入线程是为了减少程序并发执行时所付出的时间开销和空间开销,使操作系统具有更好的并发性。
因为使用进程进行并发执行时,需大量进行创建进程、销毁进程操作,系统需要为之付出较大的时空开销,因此,系统中的进程数不宜过多,进程切换的频率也不宜过高,但这就限制的并发的程度的进一步提高。因此产生了线程,目的是将进程的两个属性分开,进程依旧作为拥有资源的基本单位,线程作为处理器调度和分配的基本单位,这样可以频繁切换,并不需对资源进行频繁切换。
什么是线程
线程是进程的一个实体,是处理器调度和分配的基本单位。线程基本上不拥有系统资源,只用于少量在运行中必不可少的资源。但它可以与属于同一进程下的其他线程所拥有的全部资源。
一个线程也可创建和撤销另一个线程,同一进程直接的多个线程可并发执行,由于线程间相互制约,所以线程在运行中也呈现出间断性。
线程的属性
- 每个线程拥有一个标识符和一张线程描述表。
- 不同线程可以执行相同的程序。
- 同一进程中的各个线程共享该进程的内存地址。
- 线程是处理器的独立调度单位,多个线程可并发执行,单核处理时,多个线程交替执行,多核处理器时,各线程占用不同的处理器。
- 一个线程被创建后便开始了生命周期,直至终止,期间会经历等待、运行、就绪等状态。
线程的好处
- 创建线程时间端,开销小,相对于创建进程,速度更快,开销更小。
- 线程间切换花费时间少
- 同一进程内的多个线程共享内存和文件,且线程间通信不需经过内核,故不需要额外的通信机制,使通信更便捷,更简单。
- 线程能独立执行,能充分利用和发挥处理器与外部设备并行工作的能力。
进程和线程
线程拥有许多进程的特征,也称为轻量级进程。传统进程称为重量级进程,它相当于只有一个线程的任务。
- 调度:引入线程后,把线程处理器调度和分配的基本单位,因为线程不作为拥有资源的基本单位,所以能够轻装运行,从而显著提高系统的并发程度。在同一进程中,线程切换不会引起进程切换,相反,不是同一个进程下的两个线程切换,会引起进程切换。
- 并发性:在引入线程的操作系统中,不仅进程之间可以并发执行,而在一个进程中的多个线程也可以并发执行,因为使操作系统具有更好的并发性,从而能更有效的使用系统资源和提高系统的吞吐量。
- 拥有资源:不论使传统操作系统,还是具有线程的操作系统,进程都是拥有资源的独立单位,线程不拥有自己的系统资源(实际上拥有少量必不可少的资源),总之,一个进程中的资源可控它属下的所有进程共享。
- 系统开销:进程切换耗费的资源远远大于线程切换耗费的资源。此外,同一进程下不同线程间的通信无需内核的干预,也不需消耗额外资源。
线程实现机制
线程已在许多系统中实现,但实现的方式并不完全相同。
用户级线程
这种线程不依赖与系统内核。
用户线程只存在于用户态中,对它的创建、撤消和切换不会通过系统调用来实现,因而这种线程与内核无关。相应地,内核也并不知道有用户线程的存在,从内核角度考虑,就是按正常的方式管理,即单线程进程。
优点:
- 用户级线程可以在不支持线程的操作系统上实现。过去所有的操作系统都属于这种范围,通过这一方法,可以使用函数库实现线程。
- 允许每个进程有自己的调度算法。
内核级线程
这种线程依赖于内核。
内核线程依赖于内核,即无论是用户进程中的线程,还是系统进程中的线程,他们的创建、撤销、切换都依赖于内核实现。在内核中保留了一个线程控制块,系统根据该控制块而感知该线程的存在并对线程进行控制。
用户级线程与内核级的线程的比较
- 线程的调度与切换速度:内核级线程的调度和切换于进程的调度和切换十分相似,只是所花费的开销比进程小很多。用户级线程的切换通常是发生在一个应用进程的诸线程之间,此时,不仅无需通过中断进入操作系统的内核,而且切换规则也远比进程调度和切换的规则简单的多。
- 系统调用:传统的用户进程调用一个系统调用时,要由用户态转到内核态,用户进程将被封锁。内核完成系统调用时,才唤起该线程。当用户级线程进行系统调用的时候,内核并不知道线程的存在,因而看作整个进程的行为,于是该进程等待,而调度另一个进程执行。
- 线程执行时间:对于只设置了用户级线程的系统,调用是以进程为单位进行的。在采用轮转调度算法时,每个进程轮流执行一个时间片,这对诸进程而言是公平的。假设系统设置的是核心级线程,调度是以线程为基本单位进行的。
混合实现方式
有一些系统混合实现了用户级线程和内核级线程。
使用内核级线程,然后将用户级线程与某些或者全部内核线程多路复用起来。采用这种方法时,系统只识别内核级线程,并对其调度,其中一些内核级线程会被多个用户级线程多路复用。
进程调度
进程调度即处理器调度。
进程调度的任务是控制、协调进程对处理器的竞争,按照一定的调度算法,是某一就绪进程获得CPU的控制权,转换成运行状态。
概述
进程调度的主要功能
记录系统中所有进程的运行状态,根据一定调度算法,从就绪队列中选出一个进程,准备把处理器分配给它;把处理器分配给进程,几把选择进程的进程控制块内有关的现场信息送入处理器相应的寄存器中,从而让它占用处理器运行。
进程调度的时机
一般在以下情况发生:
- 正在执行的进程运行完毕。
- 正在执行的进程由于某种错误而终止。
- 时间片用完,即有一个进程从运行状态变为就绪状态。
- 正在执行的进程用阻塞原语将自己阻塞起来,即一个进程从运行状态进入阻塞状态。
- 创建了新的进程,即有一个进程进入就绪队列。
- 正在执行的进程调用了唤醒原语操作了等待资源的进程,即一个等待状态的进程变为就绪状态。
处理器的调度方式有两种:
- 抢占式:就绪队列中一旦有优先级高于当前运行进程的优先级时,便立即进行调度。转让处理器。
- 非抢占式(不可抢占式):一旦处理器分配给一个进程,它就一直占用处理器,直到该进程自己进入阻塞状态,或时间片用完才让出处理器。
在以上6种调度时机中,5,6是在可抢占时会引起的调度。
调度算法设计原则
进程行为
几乎所有进程的I/O请求或计算都是交替突发的。
- 计算密集型:进程花费大量时间在计算上。
- I/O密集型:进程花费大量时间在I/O等待上。
随着CPU越来越快,越来越倾向于I/O密集型。其处理思想是,让他尽快得到机会,以便发出磁盘请求并保持磁盘始终忙碌。
系统分类
不同的操作系统有不同的目标,所以需要不同的调度算法
通常可分为三类环境
- 批处理系统:在批处理系统中,不会有用户一直等待一个请求的响应。因此,非抢占式算法或对每个进程都有长时间处理周期的抢占式算法,通常是可接受的。这种处理方式减少了进程的切换从而改善了性能。
- 交互式系统:为了避免一个进程霸占处理器拒绝其他进程,抢占是必须的。服务器也归于此类,因为通常他们为多个用户服务。
- 实时系统:实时系统与交互使系统的差别就是,实时系统只运行用来推进现有应用的程序。
调度算法的设计目标
设计调度算法的目标取决于环境,例如批处理、交互式或实时,但是有些目标是适用于所有系统的。
进程调度算法
进程调度算法具有两个功能:
- 解决以何种次序对各就绪进程进行处理器分配。
- 按何种时间比例让进程占用处理器。
先来先服务算法
最简单的非抢占式算法。
- 进程按照请求处理器的顺序来使用处理器。
- 进行获取到所期望的运行时间,若发生阻塞则到队尾从新排队。
- 一个单链表记录了所有进程。
- 公平,简单,在处理长进程后处理短进程需要等待很久,周转时间长,不利于用户交互。
最短进程优先算法
一种适用于运行时可以预知的另一个非抢占式的批处理调度算法。(适用于知道进程准确的运行时间)
- 进程运行时间最短的进程优先运行。
- 只有在所有的进程都在可运行的情形下,最短进程优先算法才是最优化的。
最短剩余时间优先算法
最短进程优先算法的抢占式版本。
调度进程总是选择其剩余运行时间最短的那个进程运行。当一个新进程到达时,如比当前进程需要的时间短,则挂起当前进程,运行新的进程。
当短进程源源不断产生时,长进程一直处于等待状态,其运行得不到保证,出现这种现象我们称长进程处于”饥饿“。
最高响应比优先算法
在批处理系统中,最高响应优先算法的性能介于先来先服务算法和最短进程优先算法直接的折中算法。
为避免长进程处于饥饿,引入响应比。
响应比 = (等待时间 + 预计运行时间) / 预计运行时间 = 周转时间 / 预计运行时间
最高响应比优先算法每次调度时,选择响应比最高的线程进行调度。这种算法较好的适应了长短进程混合的系统,使调度的性能趋向于合理。
例:
进程A、B、C 到达时间分别为 0s、20s、60s,运行时间分别为80s、20s、40s
假设在三个进程全部到达时开始调度,此时分别等待了60s、40s、0s
响应比为:
A:(60 + 80) / 80 = 1.75
B:(40 + 20)/ 20 = 3
C: (0 + 20)/ 20 = 1
所以先运行B,B运行结束后在对A、C的响应比进行计算,取值较高的进行计算。
响应比在每次调度前进行计算,进程运算期间不计算,计算需要消耗系统的资源,存在一定的系统开销。
轮转算法
最早来自分时系统。
其思想是将处理的处理时间划分成等长时间片,就绪队列中的进程轮流运行一个时间片,时间片结束,运行的进程让出处理器进入就绪队列等待下一次调度。如此轮流调度,是就绪队列中的所有进程都在一个有限的时间内都获得过处理器,从而满足分时系统的要求。
在轮转算法中,时间片Q长度的选取非常重要,直接影响系统开销和响应时间。
- 过小:频繁调度进程,加重系统开销,降低处理器处理效率。
- 过大:轮转算法退化成先来先服务算法。
- 通常设置为 20 - 50 ms
影响时间片设置的几个因素:
- 系统要求的响应时间:进程数一定时,Q与系统要求的响应时间成正比。Q = T(系统要求的响应时间) / N(进程数)
- 就绪进程的数目:Q = T(系统要求的响应时间) / N(进程数)
- 计算机的处理能力:处理能力越高,时间片越小。
此外,一个进程切换需要一定时间进行管理事务处理的。需要消耗一定的时间。
最高优先级算法
每次将处理器分配给优先级最高的进程运行。进程的优先级由进程的优先数决定。
多级反馈队列算法
实际的计算机系统中,进程的调度模式往往是集中调度算法的结合。
基本思想:
- 被调度队列的设置
- 在同一队列内的调度原则
- 在不同队列内的调度原则
- 进程优先级的调整原则
系统内核
为了提高系统运行效率,保护系统关键部位不被破坏,一般把操作系统中提供支持系统运行的各种操作和基础功能的一组程序模块集中安排,形成一个操作系统核心,即内核。
内核代码只占操作系统的一小部分,是操作系统中最接近裸机的部分。可以认为裸机经过内核扩充后,形成了计算机系统的第一次虚拟机,该虚拟机没有中断,所有的进程都在这个虚拟机上运行。
内核本身不是进程,是系统进程和用户进程赖以活动的基础。因此在内存空间有限的前提下,只有内核常驻内存,其他部分根据需求调进或调出内存。
一般而言,内核提供下列功能:
- 中断处理程序
- 进程同步与互斥
- 进程调度
- 控制与通信
- 存储管理的基本操作
- 时钟管理