跳转至
阅读量:

2.1 进程与线程

思维导图

进程与线程

一、进程的概念和特征

进程的概念

在多道程序环境下,运行多个程序并发执行,此时它们将失去封闭性,并具有间断性以及不可再现性的特征。为此引入了进程(Process)的概念,以便更好的秒数和控制程序的并发执行,实现操作系统的并发性共享性

为了使参与并发执行的程序(含数据)能够独立地运行,必须为之配置一个专门地数据结构,称之为进程控制块(Process Control Block,PCB)。系统利用 PCB 来描述进程地基本情况和运行态,进而控制和管理进程。由程序段、数据段和 PCB 组成进程映像(进程实体)。要注意进程映像是动态的,而进程是静态的,进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位。

所谓创建进程,实质上是创建进程映像中地 PCB;而撤销进程,实质上是撤销进程地 PCB。

进程有着如下定义:

  • 进程是程序的一次执行过程;
  • 进程是一个程序及数据在处理机上顺序执行时所发生的活动;
  • 进程是具有独立功能的程序在一个数据集合上运行的过程,是系统进行资源分配和调度的一个独立单位。

进程的特征

进程是由多程序的并发执行而引出的,它和程序是两个截然不同的概念。

进程的基本特征是对比单个程序的执行提出的,也是对进程管理提出的基本要求:

  • 动态性(最基本的特征):进程是程序的一次执行过程,是动态地产生、变化和消亡的;
  • 并发性:指多个进程实体同时存在于内存中。引入进程的目的就是为了使程序能与其他进程的程序并发执行,以提高资源利用率;
  • 独立性:指进程实体使一个能够独立运行、独立获得资源和独立接受调度的基本单位。凡是未建立 PCB 的程序,都不能作为一个独立的单位参与运行;
  • 异步性:由于进程的相互制约,进程具有执行的间断性。异步性会导致执行结果的不可再现性,为此在操作系统中必须配置相应进程的同步机制;
  • 结构性:从结构上来看,进程实体是由程序段、数据段和 PCB 共同组成的。

二、进程的状态与转换

五种基本状态

通常进程有以下五种状态,前三种是进程的基本状态:

  • 运行态:进程正在处理机上运行,每个 CPU 每个时刻最多只有一个进程处于运行状态;
  • 就绪态:进程处于已准备运行的状态,进程此时已经获得了除处理机以外的以切资源;
  • 阻塞态(又称等待态):进程正在等待某一事件而暂停运行,例如等待资源可用,此时即使处理机空闲程序也不能运行;
  • 创建态:进程正在被创建,尚未转到就绪态;
  • 结束态:进程正在从系统中消失。

状态转换

三种基本状态的转换如下:

  • 就绪态 -> 运行态:处于就绪态的进程被调度后,获得处理机资源;
  • 运行态 -> 就绪态:处于运行态的进程在时间片用完后,必须让出处理机,从而进程由运行态转换为就绪态;
  • 运行态 -> 阻塞态:进程请求某一资源的使用和分配情况等待某一事件的发生时,它就从运行态转换为阻塞态;
  • 阻塞态 -> 就绪态:进程等待的事件到来时,中断程序必须把进程的状态由阻塞态转换为就绪态。

注意:进程从运行态转换为阻塞态是主动的行为,从阻塞态转换为就绪态是被动的行为,需要相关进程的协助。

三、进程控制

进程控制的主要功能是对系统中的所有进程实施有效的管理,它具有创建新进程、撤销已有进程、实现进程状态转换等功能。

1. 进程的创建

操作系统允许一个进程创建另外一个进程。此时创建者称为父进程,被创建的进程称为子进程。子进程可以继承父进程的拥有的所有资源。当子进程被撤销时,应将其从父进程那里获得的所有资源归还给父进程。在父进程被撤销时,必须同时撤销所有的子进程。

操作系统创建一个新进程(创建原语)的过程如下:

  • 为新进程分配一个唯一的进程标识号,并申请一个空白的 PCB(PCB 是有限的),若申请失败则创建失败;
  • 为进程分配资源,为新进程的程序和数据及用户栈分配必要的内存空间(PCB 中体现)。如果资源不足则进入等待状态;
  • 初始化 PCB,;
  • 若进程就绪队列能够接纳新进程,则将新进程插入队列,等待调度运行。

2. 进程的终止

引起进程终止的事件主要有:

  • 正常结束:进程的任务已经完成并准备退出运行;
  • 异常结束:进程在运行时,发生了某种异常事件,使进程无法正常运行;
  • 外界干预:进程应外界的请求而终止运行。

操作系统终止进程(撤销原语)的过程如下:

  • 根据被终止进程的标识符,检索 PCB,从而读出进程状态;
  • 若被终止进程处于执行状态,立即终止该进程的执行,将处理机资源分配给其它进程;
  • 若该进程还有子进程,则终止所有子进程;
  • 将进程所占用所有资源归还给父进程或操作系统;
  • 将该 PCB 从所在队列删除。

3. 进程的阻塞和唤醒

正在执行的进程由于某些期待的事情未发生,如请求系统资源失败等,由系统自动执行阻塞原语(Block),使自己由运行态变为阻塞态。因此可见,进程的阻塞是进程自身的一种主动行为,也因此只有处于运行态的进程(获得 CPU 资源),才可能将其转为阻塞态。

阻塞原语的执行过程如下:

  • 找到将要被阻塞进程的表示号对应的 PCB;
  • 若该进程为运行态,则保护其线程,将其状态转化为阻塞态,停止运行;
  • 把该 PCB 插入相应的等待队列。

当被阻塞进程所期待的事情出现时,如它所启动的 I/O 操作已完成或其所期待的数据已到达,由有关进程(如提供数据的进程)调用唤醒原语(Wakeup),将等待该事件的进程唤醒。

唤醒原语的执行过程如下:

  • 在该事情的等待队列中找到相应进程的 PCB;
  • 将其从等待队列中移出,并置其状态为就绪态;
  • 把该 PCB 插入就绪队列,等待调度程序调度。

注意:Block 原语和 Wakeup 原语是一对作用刚好相反的原语,必须成对使用。Block 原语是由被阻塞进程自我调用实现的,而 Wakeup 原语则和一个与被唤醒进程合作或被其它相关的进程调用实现的。

4. 进程切换

进程切换同样是在内核的支持下实现的,任何进程都是在操作系统内核的支持下运行的,是与内核紧密相关的。

进程切换的过程如下:

  • 保存处理机上下文,包括程序计数器和其他寄存器;
  • 更新 PCB 信息;
  • 把进程的 PCB 移入相应的队列,如就绪、在某事情阻塞等队列;
  • 选择另一个进程执行,并更新其 PCB;
  • 更新内存管理的数据结构;
  • 恢复处理机上下文。

“调度”和“切换”是有区别的:

  • 调度是指决定资源分配给哪个进程的行为,是一种决策行为;
  • 切换是指实际分配的行为,是执行行为。

一般来说,先有资源的调度,然后才有进程的切换。

四、进程的组织

进程是一个独立的运行单位,也是操作系统进行资源分配和调度的基本单位。

1. 进程控制块

进程创建时,操作系统新建一个 PCB 结构,该结构之后常驻内存,任意时刻都可以存取,并在进程结束时删除。PCB 是进程实体的一部分,是进程存在的唯一标志。

创建一个进程时,系统为该进程建立一个 PCB;进程执行时,系统通过其 PCB 了解进程的现行状态信息,以便对其进行控制和管理;进程结束时,系统收回其 PCB,该进程随之消亡。操作系统通过 PCB表来管理和控制进程。

进程描述信息 进程控制和管理信息 资源分配清单 处理机相关信息
进程标识符(PID) 进程当前状态 代码段指针 通用寄存器值
用户标识符(UID) 进程优先级 数据段指针 地址寄存器值
代码运行入口地址 堆栈段指针 控制寄存器值
程序的外存地址 文件描述符 标值寄存器值
进入内存时间 键盘 状态字
处理机占用时间 鼠标
信号量使用

PCB 主要部分介绍:

  • 进程描述信息:
  • 进程标识符:标志各个进程,每个进程都有一个唯一的标识号;
  • 用户标识符:进程归属的用户,用户标识符主要为共享和保护服务。
  • 进程控制和管理信息:
  • 进程当前状态:描述进程的状态信息,作为处理机分配调度的依据;
  • 进程优先级:描述进程抢占处理机的优先级,优先级高的进程可优先获得处理机。
  • 资源分配清单:用于说明有关内存地址空间或虚拟地址空间的状况,所打开文件的列表和所使用的输入/输出设备信息;
  • 处理机相关信息:主要指处理机中各寄存器的值,当进程被切换时,处理机状态信息都必须保存至相应的 PCB 中,以便在该进程重新执行时,能从断电继续执行。

2. 程序段

程序段就是能被进程调度程序调度到 CPU 执行的程序代码段。程序可被多个进程共享,即多个进程可以运行同一个程序。

3. 数据段

一个进程的数据段,可以是进程对应的程序加工处理的原始数据,也可以是程序执行时产生的中间或者最终结果。

五、进程的通信

进程通信是指进程之间的信息交换。PV 操作是低级通信方式,高级通信方式是指以较高的效率传输大量数据的通信方式。高级通信方式主要有以下三类:

1. 共享存储

在通信的进程之间存在一块可直接访问的共享空间,通过对这片共享空间进行对/写操作实现进程之间的信息交换。对共享空间进行写/读操作时,需要使用同步互斥工具(如 P 操作,V 操作),对共享空间的写/读进行控制。

共享存储又分为两种:

  • 低级的共享是基于数据结构的共享;
  • 高级的共享是基于存储区的共享。

操作系统只负责为通信进程提供可供享用使用的存储空间和同步互斥工具,而数据交换则由由用户自己安排读/写指令完成。

用户进程空间一般都是独立的,进程运行期间一般不能访问其它进程的空间,要想让两个用户进程共享空间,必须通过特殊的系统调用实现,而进程内的线程是自然共享进程空间的。

2. 消息传递

在消息传递系统中,进程间的数据交换是以格式化的消息(Message)为单位的。若进程间不存在可直接访问的共享空间,则必须利用操作系统提供的消息传递方法实现进程通信。进程通过系统提供的发送消息和接收消息两个原语进行数据交换。

  • 直接通信方式:发送进程直接把消息发送给接收进程,并将它挂在接收进程的消息缓存队列上,接收进程从消息缓存队列中取得消息;
  • 间接通信方式:发送进程把消息发送到某个中间实体,接收进程从中间实体获得消息。这种中间实体一般称为信箱,这种通信方式又称信箱通信方式。

3. 管道通信

管道通信是消息传递的一种特殊方式。所谓“管道”,是指用于连接一个读进程和一个写进程以实现它们之间通信的一个共享文件,又称 pipe 文件。

向管道提供输入的发送进程(写进程),以字符流形式将数据送入管道;接收进程从管道中接收数据。为了协调双方的通信,管道机制必须提供以下三方面的协调能力:互斥、同步和确定对方的存在。

注意:从管道中读取数据是一次性操作,数据一旦被读取,它就从管道中被抛弃,释放空间以便写更多的数据。管道只能采用半双工通信,要实现父子进程双方互动通信,需要定义两个管道。

六、线程概念和多线程模型

1. 线程的基本概念

引入进程的目的是更好地使多道程序并发执行,提高资源利用率和系统吞吐量。增加并发程度;而引入线程的目的是减小程序在并发执行时所付出的时空开销,提高操作系统的并发性能

线程最直接的理解就是“轻量级进程”,它是一个基本的 CPU 执行单元,也是程序执行流的最小单元,其由线程 ID、程序计数器、寄存器集合和堆栈组成。线程是进程中的一个实体,是被系统独立调度和分派的基本单位。线程不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属于一个进程的其它线程共享所拥有的全部资源。一个线程可以创建和撤销另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,让线程在运行中呈现出间断性。线程也有就绪、阻塞和运行三种基本状态。

引入线程后,进程的内涵就发生了改变,进程只作为除 CPU 外的系统资源的分配单元,线程则作为处理机的分配单元。由于一个进程内部有多个线程,若线程的切换发生在同一个进程内部,则只需要很小的系统资源。

2. 线程与进程的比较

  • 调度:在传统的操作系统中,拥有资源和独立调度的基本单位都是进程。在引入线程的操作系统中,线程是独立调度的基本单位,进程则是拥有资源的基本单位。在同一进程中,线程的切换不会引起进程的切换;不同进程之间的线程切换则会引起进程的切换。
  • 拥有资源进程是拥有资源的基本单位,线程可以访问隶属于进程的系统资源;
  • 并发性:进程之间可以并发执行,多个线程之间也可以并发执行;
  • 系统开销:操作系统在创建进程和撤销进程上的开销远大于创建线程和撤销线程上的;
  • 地址空间和其它资源:进程的地址空间之间相互独立,同一进程的所有线程共享进程的资源;
  • 通信方面:进程间通信(IPC)需要进程同步和互斥手段的辅助,以保证数据的一致性;而线程间可以直接读/写进程数据段来进行通信。

3. 线程的属性

多线程操作系统将线程作为独立运行和调度的基本单位,此时进程不再是一个基本的可执行实体,但它仍具有与执行相关的状态。所谓进程处于“执行”状态,实际上是指该进程中的某县城正在执行。

线程的主要属性如下:

  • 线程是一个轻型实体,不拥有系统资源。但每一个线程都有一个唯一的标识符和线程控制块,线程控制块记录了线程执行的寄存器和栈等线程状态;
  • 不同的线程可以执行相同的程序;
  • 同一进程中的各个线程共享该进程所拥有的资源;
  • 线程是处理机的独立调度单位,多个线程是可以并发执行的。单核 CPU 中各线程可以交替地占用 CPU,
  • 一个线程被创建后,便开始了它的生命周期,直至终止。

4. 线程的实现方式

线程的实现方式可以分为两类:用户级线程(User-Level Thread,ULT)和内核级线程(Kernel-Level Thread,KLT),内核级线程又称内核支持的线程。

在用户级线程中,有关线程管理的所有工作都由应用程序完成,内核意识不到线程的存在。应用程序可以通过使用线程库设计多线程程序。通常情况下,应用程序从单线程开始,在其运行的任何时刻都可以调用线程库创建新的线程。

在内核级线程中,线程管理的所有工作都由内核完成,应用程序没有进行线程管理的代码,只有一个到内核级线程编程的接口。内核进程为进程及内部的每个线程维护上下文信息,调度也在内核基于线程架构的基础上完成。

有些系统中使用组合方式的多线程实现。线程创建完全在用户空间完成,线程的调度和同步也都在应用程序中进行。一个应用程序中的多个用户级线程被映射到一些(小于等于用户级线程)内核级线程上。

5. 多线程模型

有些系统同时支持用户线程和内核级线程,由此产生了不同的多线程模型(即实现用户级线程和内核级线程的连接方式):

  • 多对一模型:将多个用户级线程映射到一个内核级线程,线程管理在用户空间完成。此模式中,用户级线程对操作系统不可见(透明);
  • 一对一模型:将每个用户级线程映射到一个内核级线程;
  • 优点:当一个线程被阻塞后允许另外一个线程继续执行,因此并发能力强;
  • 缺点:每创建一个用户级线程都需要创建一个内核级线程与其对应,这样创建线程的开销比较大,会影响到应用程序的性能。
  • 多对多模型:将 n 个用户级线程映射到 m 个内核级线程上,要求 m <= n。
  • 特点:多对多模型是多对一模型和一对一模型的折中,即克服了多对一模型并发度不高的缺点,又克服了一对一模型的一个用户进程占用太多内核级线程而开销太大的缺点。同时又拥有两种模型各自的优点。

参考资料:王道考研——操作系统

评论