文章目录
- 1. 进程的基本概念
- 1.1 程序的顺序执行
- 1.2 程序的并发执行
- 1.3 进程的定义与特征
- 1.4 进程的状态
- 1.4.1 进程的基本状态
- 1.4.2 进程的挂起状态
- 1.5 进程控制块
- 2. 进程控制
- 2.1 操作系统内核
- 2.2 进程的创建
- 2.3 进程的终止
- 2.4 进程的阻塞和唤醒
- 2.5 进程的挂起与激活
- 3. 进程同步
- 3.1 进程同步的概念
- 3.1.1 两种制约形式
- 3.1.2 临界资源和临界区
- 3.1.3 同步机制应遵循的规则
- 3.2 信号量机制
- 3.3 信号量的应用
- 4. 经典进程的同步问题
- 4.1 生产者——消费者问题
- 4.2 哲学家进餐问题
- 4.3 读者——写者问题
- 5. 管程机制
- 5.1 管程的定义
- 5.2 条件变量
- 5.3 利用管程解决生产者——消费者问题
- 6. 进程通信
- 6.1 进程通信的类型
- 6.2 消息缓冲队列通信机制
- 7. 线程
- 7.1 线程的基本概念
- 7.2 线程的控制
- 7.3 内核支持线程和用户级线程
1. 进程的基本概念
1.1 程序的顺序执行
程序的顺序执行是指若干个程序或程序段之间必须严格按照某种先后次序来执行,仅当前一段程序或程序段执行完后,才能执行后面的程序或程序段。
程序的顺序执行具有下列特征:
- 顺序性。处理机按照程序所规定的顺序执行。
- 封闭性。程序在执行时独占系统的全部资源,因此,系统资源状态的改变只与执行的程序有关,而不受外界因素的影响。
- 可再现性。只要初试条件相同,一个程序的多次重复执行将得到相同的结果。
1.2 程序的并发执行
程序的并发执行是指两个或两个以上的程序或程序段在同一时间间隔内同时执行。
程序的并发执行极大地提高了资源利用率和系统吞吐量,同时也产生了不同于顺序执行的新特征:
- 间断性。由于资源共享和相互合作,并发执行的程序间形成了相互制约的关系,导致程序的运行过程出现“执行——暂停——执行”的现象。
- 失去封闭性。程序在执行时与其它并发执行的程序共享系统的资源,因此,资源状态的改变还与其他程序有关,即程序本身的执行环境受到外界程序的影响。
- 不可再现性。同样的初始条件,一个程序的多次重复执行可能会得到不同的结果。
1.3 进程的定义与特征
程序并发执行时产生的不可再现性,决定了通常的程序是不能参与并发执行的。为了使程序能够正确地并发执行,并且可以对并发执行的程序加以描述和控制,操作系统中引入了进程的概念,用进程来表示一个并发执行的程序。
传统OS中进程定义:进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位。
特征:
- 动态性。进程是程序一次执行过程,因此是动态的,进程的动态性还表现在进程具有一定的生命期,它必须由创建而产生、由调度而执行、由撤销而消亡。动态性是进程的一个最基本的特征。
- 并发性。并发性是指多个进程实体同存于内存中,且能在一段时间内同时执行。只有为程序创建进程后,多个程序才能正确地并发执行。并发是引入进程的目的,也是进程的另一个最基本的特征。
- 独立性。进程实体是一个能够独立运行、独立分配资源和独立接受调度的基本单位。
- 异步性。进程可按各自独立的、不可预知的速度向前推进。虽然进程具有异步性,但操作系统必须保证进程并发执行的结果是再现的。
1.4 进程的状态
1.4.1 进程的基本状态
- 就绪状态。进程已经获得CPU以外的所有必要资源,只要得到CPU,便可立即执行。
- 执行状态。进程已得到CPU,其程序正在CPU上执行。
- 阻塞状态。正在执行的进程因某种事件(如I/O请求)的发生而暂时无法继续执行,只有等相应事件完成后,才能去竞争CPU。
对单个进程而言,任何时刻,它只能处于三种基本状态之一。对整个系统而言,每个时刻允许同时有多个进程处于就绪状态,通常它们组成一个或多个就绪队列;也允许同时有多个进程处于阻塞状态,并将它们组成一个或多个阻塞队列;但对执行状态的进程,每个处理机最多只允许有一个。
进程调度
时间片完
等待I/O操作或其他事件
I/O操作或其他事件完成
创建
就绪
执行
阻塞
终止
1.4.2 进程的挂起状态
挂起实质是进程不能继续执行,即使挂起后的进程处于就绪状态,它也不能参与CPU竞争。挂起常被用在进程的对换中,此时,挂起(即换出)进程可以腾出内存空间给就绪进程使用;挂起还可以用在其它场合,如用来调节系统的符合、方便用户考查自己的运行进程或父进程考查子进程、方便操作系统检查系统运行中的资源使用情况或进行记账等。
挂起
激活
时间片用完
调度
I/O请求
I/O完成
挂起
激活
I/O完成
挂起
活动就绪
静止就绪
执行
活动阻塞
静止阻塞
1.5 进程控制块
为了描述和控制进程的运行,构造的一种特殊数据结构——PCB。PCB 是进程实体的一个组成部分,在 PCB 中记录了 OS 所需的、用于描述进程的当前情况以及控制进程的全部信息。
PCB 的作用是将程序变成可并发执行的进程。系统根据 PCB 感知到进程的存在,并通过 PCB 对进程进行控制,因此,PCB 是进程存在的唯一标志。
进程控制块中通常包含以下信息:
- 进程标识符。用于唯一标识系统中的每个进程;缺点父子关系。
- 处理机状态。用于 CPU 切换时保存现场信息和恢复现场信息。
- 进程调度信息。进程调度信息主要包括进程状态、优先级、等待和使用 CPU 的时间总和等信息,用作进程调度和对换的依据。
- 进程控制信息。包括了程序和数据的地址、进程同步和通信信息、资源清单和进程队列指针等。
为了便于管理,系统通常用线性方式或链接方式或索引方式将这些 PCB 组织起来。
2. 进程控制
操作系统的内核通过原语1实现。
2.1 操作系统内核
现代操作系统一般将 OS 划分为若干层次,再将 OS 的不同功能,分别设置在不同的层次中。通常将一些与硬件紧密相关的模块(如中断处理程序等)、各种常用设备的驱动程序以及运行频率较高的模块(如时钟管理、进程调度和许多模块所公用的一些基本操作),安排在紧靠硬件的软件层次中,将它们常驻内存,这部分通常称为 OS 内核。
为了使操作系统内核代码和数据不会遭受用户程序的破坏,通常将处理机的执行状态分为系统态和用户态两种不同状态:
- 系统态:也叫管态或内核态,它具有较高的特权,能执行一切指令,访问所有寄存器和存储区。
- 用户态:也叫目态,是一种具有较低特权的执行状态,它只能执行规定的指令,访问特定的寄存器区和存储区。
通常,操作系统内核运行在系统态,而用户程序都运行在用户态。
2.2 进程的创建
导致一个进程去创建另一个进程的典型事件有分时系统中的用户登录和批处理系统中的作业调度。另外,应用程序本身也可以根据需要去创建新的进程。创建进程是通过创建原语完成的,被创建的进程称作子进程,而创建子进程的进程称作父进程。
进程创建原语的主要任务是创建 PCB。具体:先从 PCB 集合中申请一个空闲的 PCB,再为新进程分配内存等资源,并根据父进程提供的参数和分配到的资源情况来对 PCB 进程初始化,最后将新进程插入到就绪队列。
2.3 进程的终止
实质是收回 PCB。具体:找到要终止进程的 PCB;若该进程正在执行,则终止它的执行,并设置重新调度标志;终止属于该进程的所有子孙进程;释放进程所拥有的全部资源;将终止进程移出它所在的队列并收回 PCB。
2.4 进程的阻塞和唤醒
当正在执行的进程需要等待某种事件的完成或本身无新工作可做时,应调用阻塞原语将自己从执行状态转换成阻塞状态。具体:停止进程的执行,将其状态改为阻塞状态,并把它的 PCB 插入相应的阻塞队列,转调度程序重新调度。当阻塞进程所等待的事件完成时,应调用唤醒原语将该进程的状态从阻塞状态换成就绪状态。在阻塞队列中移出该进程的 PCB,将其设置成就绪状态,并把它插入就绪队列。
2.5 进程的挂起与激活
具体:若进程处于活动阻塞状态,则将它的状态转换成静止阻塞状态;否则,将它转换成就绪状态;将 PCB 复制到指定的内存区域供用户或父进程考查;若挂起进程正在执行,则转调度程序重新进行进程调度。如果挂起是为了对换,则在挂起进程时还必须将它换出到内存中。若进程处于禁止阻塞状态,则将它转换成活动阻塞状态,否则将它装换成活动就绪状态;若进程转换成活动就绪状态,而系统又采用抢占调度策略,则应检查该进程是否有权抢占CPU,若有则应进行进程调度。同样,如果挂起是为了对换,则在激活被挂起的进程时还必须将它调入内存。
3. 进程同步
3.1 进程同步的概念
3.1.1 两种制约形式
- 间接相互制约。源于资源共享。
- 直接相互制约。源于进程合作。
3.1.2 临界资源和临界区
在计算机中有许多资源一次只能允许一个进程使用,如果多个进程同时使用这些资源,则有可能造成系统混乱,这些资源被称作临界资源。
每个进程中,访问临界资源的那段代码称作临界区。
3.1.3 同步机制应遵循的规则
- 空闲让进。临界资源空闲时,应允许一个请求进入临界区的进程立即进入自己的临界区,以便有效地利用资源。
- 忙则等待。当临界资源正被访问时,其他要求进入临界区的进程必须等待,以保证对临界资源的互斥使用。
- 有限等待。任何要求访问临界资源的进程应能在有限的时间内进入自己的临界区,以免“死等”。
- 让权等待。不能进入临界区的进程应立即释放CPU,以免“忙等”。
3.2 信号量机制
- 整型信号量。
- 记录型信号量。
3.3 信号量的应用
- 利用信号量实现前趋关系
- 利用信号量实现互斥
4. 经典进程的同步问题
4.1 生产者——消费者问题
4.2 哲学家进餐问题
4.3 读者——写者问题
5. 管程机制
5.1 管程的定义
管程利用共享数据结构抽象地表示系统中的共享资源,并且将对该共享数据结构实施的特定操作定义为一组过程。换句话说,管程是由一组局部的共享变量、对局部变量进行操作的一组过程以及对局部变量进行初始化的语句序列构成的一个软件模块。
管程具有以下特点:
- 管程内的局部变量只能被局部于管程的过程所访问,反之亦然,即局部于管程内的过程只能访问管程内的变量和形式参数。
- 任何进程只能通过调用管程提供的过程入口进入管程。
- 任一时刻,最多只能有一个进程在管程中执行。
5.2 条件变量
5.3 利用管程解决生产者——消费者问题
6. 进程通信
6.1 进程通信的类型
- 共享存储器系统。
- 管道通信。
- 消息传递系统。
- 客户机——服务器系统。
- 套接字。
- 远程过程调用和远程方法调用。
6.2 消息缓冲队列通信机制
- 消息缓冲队列通信机制中的数据结构。
- 发送原语。
- 接受原语。
7. 线程
7.1 线程的基本概念
7.2 线程的控制
7.3 内核支持线程和用户级线程
- 用户级线程。用户级线程仅存在于用户空间中,与内核无关。就内核而言,它只是管理常规的进程——即单线程进程,感知不到用户级线程的存在。用户级线程的优点是不需要得到内核的支持。线程切换无须陷入内核,故切换开销小。线程库对用户线程的调度算法与 OS 的调度算法无关,因此,线程库可提供多种调度算法供应用程序选择使用。但在纯用户级线程的系统中,对应用程序来讲,当一个线程因为执行系统调用而阻塞时,将导致对应进程中所有进程的阻塞,另外,用户级线程无法享用多处理机系统中多个处理器带来的好处。
- 内核支持线程。内核支持线程是在核心空间实现的。内核为每个线程在核心空间中设置了一个线程控制块,用来登记该线程的线程标识符、寄存器值、状态、优先级等信息。所有对线程的操作,如创建、撤销和切换等,都是通过系统功能调用内核中的相应处理程序完成的。内核支持线程克服了用户级线程的两个缺点,首先,内核可以把同一个进程中的多个线程调度到多个处理器中;其次,如果进程中的一个线程被阻塞,内核可以调度同一个进程中的另一个线程。它的另一个优点是内核本身也可以使用多线程的方式来实现。它的主要缺点是即使 CPU 在用一个进程内的多个线程之间切换,也需要陷入内核,因此,其速度和效率不如用户级线程。
- 组合方式。n(用户级线程):1(核心线程)、1:1、n(用户线程):m(核心线程)。
- 原语是指由若干条指令组成、用来实现某个特定操作的一个过程。原语的执行具有原子性,即原语在执行过程中不允许被中断,通常常驻内存,且在系统态下执行。↩︎