【操作系统】进程/线程模型

1. 进程的基本概念

1.1 多道程序设计(Multi-Programming)

首先从多道程序设计开始,以便更好的理解进程的必要性。
在早期没有多道程序设计之前,操作系统只有一个物理程序计数器,这样多个程序只能串行执行,在引入多道程序之后,一个物理程序计数器可以被拆分成多个逻辑程序计数器每个程序都有其独有的程序计数器,从而实现程序的并发执行。
所谓的多道程序设计,是指允许多个程序同时进入内存并运行,目的在于提高系统效率。

1.2 并发环境与并发程序

并发环境:一段时间间隔内,单处理器上有两个或两个以上的程序同时处于开始运行但尚未结束的状态,并且运行次序不是事先确定的。
并发程序:在并发环境中执行的程序。

在并发环境下,每个程序的运行状态应该怎样去刻画呢?这个时候进程就应运而生了。

1.3 进程的定义

Process:进程是具有独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和CPU调度的独立单位。进程又称任务(Task or Job)。

进程可以理解为程序的一次执行过程,操作系统为每个进程分配了一独立的地址空间。
操作系统为了统一管理所有进程,需要一个专门的数据结构——进程控制块。

1.4 进程控制块PCB(Process Control Block)

又称为进程描述符、进程属性,是操作系统用于管理进程的专门的数据结构。PCB记录了进程的各种属性。是系统感知进程存在的唯一标识,和进程是一一对应的关系。
进程表:操作系统中所有进程的PCB集合。
PCB应该包含哪些内容呢?如下表:
表1-1 PCB模块及内容

模块 内容
进程描述信息 进程唯一标识符(Process ID);进程名,用户标识符(User ID)等
进程控制信息 当前进程状态,优先级,代码执行入口地址,进程间同步和通信,进程的队列指针
所拥有的资源信息和使用情况 虚拟地址空间状况,打开的文件列表
CPU现场信息 寄存器值(通用寄存器,程序计数器PC、程序状态字PSW、栈指针);指向该进程页表的指针

1.5 例子:SOLARIS的进程控制块和进程表简介

在这里插入图片描述

2. 进程的状态及状态转换

2.1 进程的三种基本状态及状态转换

2.1.1进程是三种基本状态

表2-1进程的三种基本状态

进程状态 特点
运行态(Running) 占有CPU并在CPU上运行
就绪态(Ready) 已经具备运行条件,但是由于没有空闲的CPU而暂时不能运行
等待态(Waiting/Blocked) 也叫阻塞态、封锁态、睡眠态;是指程序因为等待某一事件(如等待磁盘I/O读取结果)而不能运行
2.1.2 进程的三状态模型及状态转换

在这里插入图片描述

2.2 进程的其他状态及复杂的状态模型

2.2.1 进程的其他状态
进程状态 特点
创建(new) 已完成创建一个进程所必要的工作但由于资源有限操作系统尚未同意执行该进程
终止(terminated) 进程终止执行后的状态,此时可完成一些统计工作和资源回收工作
挂起(suspend) 用于负载调节,该状态下的进程不占用内存空间,把进程相关内容保存到本地磁盘上,激活时需要从磁盘中读取

在引入进程这三种状态之后,进程的状态模型可能会变得复杂。

2.2.2 五状态进程模型

在这里插入图片描述

2.2.3 七状态进程模型

在这里插入图片描述

2.3 Linux的状态模型

在这里插入图片描述

2.4 进程队列

2.4.1 概念

进程的状态是如何进行控制的呢?事实上操作系统为每一类状态的进程建立了一个或多个队列,队列元素为PCB,进程状态的改变本质上就是进程对应的PCB从一个队列进入到另一个队列

多个等待队列表示每个队列等待的事件不同,同一个等待队列中所有的PCB等待的是相同的事件。

2.4.2 五状态进程模型的队列模型

在这里插入图片描述

3 进程控制

进程控制操作完成进程各状态之间的转换,由具有特定功能的原语完成。如进程创建原语、阻塞原语、唤醒原语等。

原语(primitive):完成某种特定功能的一段程序,具有不可分割性和不可中断性,是原子操作。

3.1 进程的创建

  • 给新进程分配一个唯一标识和进程控制块PCB
  • 分配地址空间
  • 初始化进程控制块,设置默认值
  • 设置相应的队列指针,如把新进程加到就绪队列中
    在UNIX系统中通过fork/exec组合指令完成

3.2 进程的撤销

  • 回收进程所占有的资源,如关闭打开的文件、断开网络连接等
  • 撤销该进程的PCB
    在UNIX系统中通过exit指令完成

3.3 进程的阻塞

处于运行状态的进程,在其运行过程等待某一事件发生,如等待键盘录入、等待磁盘I/O等,由进程自己执行阻塞原语从而进入阻塞态。
在UNIX系统中通过wait指令完成

3.4 UNIX系统中的几个进程控制操作

3.4.1 概述
  • fork():通过复制调用进程来建立新的进程,是最基本的进程创建过程
  • exec():包括一系列系统调用,它们都是通过用一段新的程序代码覆盖原来的地址空间,实现进程执行代码的转换
  • wait():初级进程同步操作,使得一个进程能够等待另外一个进程的结束
  • exit():用来终止一个进程的运行
3.4.2 UNIX的fork()实现
  • 为子进程分配一个空间的进程描述符PCB proc结构
  • 分配给子进程唯一标识pid
  • 以一次一页的方式复制父进程地址空间(此乃UNIX系统fork较慢的主要原因)
  • 从父进程处继承共享资源,如打开的文件和当前工作目录等
  • 将子进程的状态设置为就绪,插入到就绪队列
  • 向子进程返回标识符0
  • 向父进程返回子进程的pid
    注意:UNIX下的fork()把父进程的所有地址空间都拷贝给了子进程,但实际上子进程根本用不到这些内容,所以在Linux下利用写时复制Copy-On-Write(COW)技术加快了创建进程。

4 进程相关概念

4.1 进程地址空间

我们知道**,操作系统给每个进程都分配了一个独有的地址空间**。但这个地址空间不是物理内存位置,而是相对的地址空间。

4.2 进程映像(Image)

是对进程执行活动全过程的静态描述,可以理解为进程快照。由进程地址空间内容、硬件寄存器内容及与该进程相关的内核数据结构、内核栈组成。

  • 用户相关:进程地址空间(包含代码段、数据段、堆和栈)
  • 寄存器相关:程序计数器、指令寄存器、程序状态字、栈指针
  • 内核相关:
    ①、静态部分:PCB及各种资源数据结构
    ②、动态部分:内核栈(不同进程拥有独立的内核栈)

4.3 上下文(Context)切换

将CPU硬件状态从一个进程切换到另一个进程的过程称为上下文切换。

  • 程序运行时,硬件状态保存在CPU上的寄存器中,寄存器包括:程序计数器、程序状态字寄存器、栈指针、通用寄存器以及其它控制寄存器的值
  • 程序运行时,这些寄存器的值保存在进程控制块PCB中,当操作系统要运行一个新的进程时,将PCB中相关的值送到对应的寄存器中。

5 线程的引入

我们知道,进程已经可以实现并发程序运行,那么为什么还要再派生线程呢?

表5-1 线程的必要性

必要性 说明
应用的需要 如Web服务器,从客户端接收网页请求,从磁盘检索相关网页并读入内存,然后将网页返回给客户端,当然,为了提高效率,Web服务器都有网页缓存(Web page cache)。如果没有线程,只能有一个服务进程(不可以有多个服务进程,因为每个进程都有自己的内存地址,这样就不能共享信息),这个时候只能是顺序编程,服务进程在搜索网页的时候就不能接受新的客户端请求,性能较差
开销的考虑 线程的开销比进程小很多,创建、撤销线程花费时间较短;两个线程切换花费的时间少;线程之间的通信无需调用内核(同一进程内的线程共享内存和文件
性能的考虑 当有多个处理器的时候,一个进程内有多个线程就可以实现线程的分工合作(有的计算、有的处理I/O等),则能提高性能

5.1 线程的基本概念

先来回顾一下上面说的:进程的两个属性是:资源的拥有者和CPU调度单位。引入线程之后,CPU调度单位就不再是进程,转而变成了线程。但进程依然是资源的拥有者。

线程是进程的一个运行实体,是CPU的调度单位,有时将线程称为轻量级进程。事实上线程的出现可以理解为是进程中增加了多个执行序列。

5.2 线程的属性

  • 唯一标识符
  • 有状态的转换
  • 有上下文环境:程序计数器等寄存器
  • 有自己的栈和栈指针
  • 共享所在进程的地址空间和其他资源
  • 可以创建、撤销另一个线程,实际上程序开始时是以一个单线程进程方式进行的

6 线程实现机制

主要有三种:用户级线程(User Level Thread)、内核级线程(Kernel Level Thread)及混合型。
表6-1 线程模型及典型应用

线程模型 特征 典型应用 优缺点
用户级线程 在用户空间创建线程库。由运行时系统完成线程的管理,内核管理的是进程,并不清楚线程的存在,线程的切换不需要内核态特权 UNIX 优点:线程切换快,可运行在任何操作系统上;缺点:内核只将CPU分配给进程,同一个进程中的两个线程不能同时运行在两个处理器上(即便有多个CPU),大多数系统调用是阻塞的,由于内核阻塞进程,故进程中的所有线程都会被阻塞。
内核级线程 内核管理所有线程,内核既管理进程也管理了线程,线程的切换需要内核支持,以线程为基础进行调度 Windows
混合模型 线程的创建是在用户空间完成的,调度等是在内核空间完成的,多路复用 Solaris

小结

在介绍了进程和线程之后,还要引入一个重要概念:
可再入程序(可重入)
被多个进程同时调用的程序,具有如下性质:

  • 是纯代码的,即在执行过程中自身不改变
  • 调用的它的进程应该提供数据区,改变只能在数据区改变。
发布了40 篇原创文章 · 获赞 15 · 访问量 43万+

猜你喜欢

转载自blog.csdn.net/Carson_Chu/article/details/104166924