【操作系统·考研】进程与线程

【操作系统·考研】进程与线程_第1张图片

1.进程

1.1 概述

  • 进程概念的引入,是为了更好地描述和控制程序的并发执行,实现现代OS的并发性和共享性。
  • 系统必须为每一个进程配置一个进程控制块(Process Control Block,PCB),以描述进程的基本情况和运行状态。
  • 进程实体 = 程序段 + 相关数据段 + PCB
  • 进程映像是静态的,进程是动态的。
  • PCB是进程存在的唯一标志。
  • 进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位。(这里的系统资源是指处理机、存储器和其他设备服务于进程的时间)

1.2 特点

  1. 动态性。进程是程序的一次执行,它有创建、活动、暂停、终止等过程,具有一定的生命周期,是动态产生、变化和消亡的。(最基本的特征)
  2. 并发性。多个进程实体同时存在于内存中,能在一段时间内同时运行。
  3. 独立性。进程实体是一个能独立运行、独立获得资源和独立接受调度的基本单位。未建立PCB的进程不能参与运行。
  4. 异步性。由于进程的相互制约,导致每个进程都按照各自独立的、不可预知的速度向前推进,这会进一步带来结果上的不可再现性。

1.3 状态

  1. 运行态。进程正在处理机上运行。(单处理机中,每个时刻只能有一个进程处于运行态)
  2. 就绪态。进程获得了除处理机外的一切所需资源,一旦得到处理机,便可立即运行。系统中处于就绪态的进程可能有多个,通常将它们排成一个队列,称为就绪队列。
  3. 阻塞态/等待态。进程正在等待某一事件而暂停运行,如等待某个资源可用或等待I/O完成,即使处理机空闲,该进程也不能运行。通常系统也将多个处于阻塞态的进程排成一个队列,按照阻塞原因的不同,设置多个阻塞队列。
  4. 创建态。进程正在被创建,尚未进入就绪态。进程创建过程:申请一个空PCB并填写进入用于管理和控制的进程信息 -> 为该进程分配运行时所需的资源(此步骤失败,则进程的状态就处于创建态) -> 将该进程转入就绪队列。
  5. 终止态。进程正常结束工作或因某些原因退出运行。结束运行时,系统先将该进程设置为终止态,然后再去释放并回收其占用的资源。

就绪态与等待态的区别:
就绪态是万物具备,只欠处理机;等待态是以及占有了处理机而等待其他资源或事件。

1.4 状态转换

  1. 就绪态 -> 运行态:进程将获得处理机资源(被分配处理机时间片)。
  2. 运行态 -> 就绪态:处于运行态的进程在自己的时间片用完后,将不得不让出处理机,从而进入就绪状态。在可剥夺的OS中,当有更高优先级的进程就绪时,将会剥夺当前运行进程的处理机资源,让其进入就绪态。
  3. 运行态 -> 阻塞态:进程将请求某一资源的分配或等待某一事件的发生。进程以系统调用的方式请求OS为其提供服务,这是一种特殊的、由运行用户态程序调用OS内核过程的形式。(主动行为)
  4. 阻塞态 -> 就绪态:进程等待的事件到来,中断处理程序则将相应的进程状态改为就绪态。(被动行为)

【操作系统·考研】进程与线程_第2张图片

1.5 组成

1.5.1 进程控制块(PCB)

1.5.1.1 概述
  • 进程创建时,OS会为其创建一个PCB,PCB之后会常驻内存,并在进程结束时销毁。
  • PCB是进程实体的一部分,是进程存在的唯一标志。
  • 进程运行时,OS将通过PCB了解该进程的实时状态信息。
  • 当OS欲调度某个进程运行时,会先从该进程的PCB中查出其运行状态和优先级,在调度到某进程后,又根据PCB中保持的处理机的状态信息设置恢复运行的现场,同时查出该进程对应的PCB中的程序段和数据段内存起始地址。
  • 当进程间需要通信、同步和访问文件时,也需要访问PCB。
  • 当进程因某种原因暂停运行时,其断点处的处理机环境将被保存到PCB中。
  • 为了便于管理若干处于不同状态的进程的PCB,需要借助链接方式索引方式进行组织:
    • 链接方式:将同一状态的PCB串联成一个队列,不同状态对应不同的队列。对于阻塞态,也可以根据阻塞原因的不同进一步划分为多个阻塞队列。
    • 索引方式:将同一状态的进程组织进同一个索引表中,其表项指向相应的PCB,不同状态对应不同的索引表。
1.5.1.2 结构
进程描述信息 进程控制和管理信息 资源分配清单 处理机相关信息
进程标识符(PID) 进程当前状态 代码段指针 通用寄存器值
用户标识符(UID) 进程优先级 数据段指针 地址寄存器值
代码运行入口地址 堆栈段指针 控制寄存器值
程序的外存地址 文件描述符 标志寄存器值
进入内存时间 键盘 状态字
处理机占用时间 鼠标
信号量使用
  • 进程描述信息
    • 进程标识符:每个进程都有一个唯一的标识号。
    • 用户标识符:进程归属的用户,用户标识符主要为共享和保护服务。
  • 进程控制和管理信息
    • 进程当前状态:处理机的分配的依据之一。
    • 进程优先级:描述进程抢占处理机的优先级,优先级高的进程可优先获得处理机。(分为静态优先级和动态优先级,动态优先级可根据运行时情况而调整)
  • 资源分配清单:用于说明有关内存地址空间或虚拟地址空间的状况,所打开的文件列表以及所使用的I/O设备信息。
  • 处理机相关信息/处理机上下文:主要指处理机中各寄存器的值。进程切换时,其处理机状态信息必须存入相应的PCB中以便该进程重新执行时能从断点处继续执行。

【操作系统·考研】进程与线程_第3张图片

1.5.2 程序段

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

1.5.3 数据段

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

对于C语言中的内容:
其全局赋值变量存放在共享正文段;
其未赋值的局部变量存放在数据栈段;
其函数调用实参传递值存放在数据栈段;
用malloc()函数动态分配的存储区存放在数据堆段;
常量值(如1995、“IKUN”)存放在共享正文段;
进程的优先级存放在PCB中。

1.6 进程控制

1.6.1 进程创建

1.6.1.1 概述

一个进程(父进程)可以创建另一个进程(子进程),子进程将继承父进程所占有的资源,子进程销毁时,其从父进程获得的资源将被归还给父进程。父进程被销毁时,其所有子进程将被销毁。

1.6.1.2 过程
  1. 为新进程分配一个新的PID,并申请一个空白的PCB。(由于PCB数量有限,因此这里可能申请失败,若申请失败,则本次进程创建过程宣告失败)
  2. 为进程分配所需要的资源,如内存、文件、I/O设备、CPU时间等。这些资源将从OS或父进程获得。若此过程未能获得全部必需资源,则进程进入创建态,等待全部所需资源被分配。
  3. 初始化PCB。主要包括初始化标志信息、处理机状态、处理机控制信息和设置进程的优先级等工作。
  4. 若就绪队列能够接纳新的进程,则将新进程push到就绪队列,等待被处理机调度运行。

父进程可以和子进程并发执行。
父进程不能和子进程共享虚拟地址空间。父进程创建子进程时,会为其分配虚拟地址空间。
父进程与子进程有不一样的PCB。(毕竟PCB是进程存在的唯一标志嘛。。。)

父进程创建子进程后,父进程与子进程同时并发执行。
主程序调用子程序后,主程序停在调用点,子程序开始执行,直到子程序返回时,主程序才继续运行。

1.6.2 进程阻塞

1.6.2.1 概述

正在运行的进程(已获得CPU),由于期待的某些事件未发生,如请求系统资源失败、等待某种操作的完成、新数据尚未到达、五新任务可做等,进程便通过主动调用阻塞原语(Block),式自己由运行态转为阻塞态。

1.6.2.2 过程
  1. 找到将被执行阻塞操作的PID对应的PCB。
  2. 若该进程处于运行态,则保存现场信息,然后将其转为阻塞态,停止运行。
  3. 将该进程对应的PCB push到等待队列中,然后将处理机资源调度给其他就绪进程使用。

1.6.3 进程唤醒

1.6.3.1 概述

当被阻塞的进程所期待的事件发生时,如它所期待的I/O操作已完成、所期待的数据已到达等,其他进程(如释放该I/O设备的进程、提供数据的进程等)将调用唤醒原语(Wakeup),将等待该事件的进程唤醒。

1.6.3.2 过程
  1. 在该事件的等待队列中找到相应的进程的PCB。
  2. 将其PCB从等待队列中移出,并将其状态置为就绪态。
  3. 将其PCBpush到就绪队列中,等待被处理机调度运行。

Block原语与Wakeup原语必须成对使用,若某一进程调用了Block,其合作的另一进程必须能够调用Wakeup,否则它将永远无法被唤醒而处于阻塞状态。

1.6.4 进程终止

1.6.4.1 概述

引起进程终止的原因主要有:

  1. 正常结束。进程任务已完成并准备退出运行。
  2. 异常结束。进程在运行时,发生某种异常事件致使其无法正常继续运行,如存储区越界、保护错、非法指令、运行超时等。
  3. 外界干预结束。进程应外界的请求而终止运行,如操作员或OS干预、父进程请求或终止等。
1.6.4.2 过程
  1. 根据需要被终止的进程的PID,检索出对应的PCB。
  2. 获取该进程的运行状态,若该进程处于运行状态,则立即终止该进程的运行,并将处理机资源分配给其他进程。
  3. 若该进程还有子进程,则将其子进程一并终止。
  4. 将该进程占有的资源归还给OS或其父进程。
  5. 将其PCB从所在队列中删除。

1.7 进程通信

1.7.1 共享存储

1.7.1.1 概述

在通信的进程之间存在一块可直接访问的共享空间,通过对这块共享空间的读写可完成进程间的信息交换。
【操作系统·考研】进程与线程_第4张图片

由OS负责需要共享的存储空间和同步互斥工具,数据交互则由双方进程自行安排读/写指令完成。

进程空间不可共享,但隶属于同一进程的若干线程共享该进程空间。

1.7.1.2 分类
  • 基于数据结构的共享(低级)
  • 基于存储区的共享(高级)

1.7.2 消息传递

1.7.2.2 概述
  • 该方式下,进程间的数据交换是以格式化的消息(Message)为单位进行的。通信双方通过系统提供的消息发送消息接收两个原语进行数据交换的。
  • 这种通信方式隐藏了通信实现的细节,通信过程对用户透明,简化了通信程序的设计,同时也能很好的支撑多处理机OS、分布式OS、计算机网络。
  • 微内核OS中,微内核与服务器的通信就是采用消息传递的方式。

【操作系统·考研】进程与线程_第5张图片

1.7.2.3 分类
  • 直接通信方式。发送进程直接把消息发生给接收进程,并将它挂载到接收进程的消息缓冲队列上,然后接收进程从该消息缓冲队列上取得消息。
  • 间接通信方式。发送进程将消息发送到某个中间实体(一般称之为信箱),然后接收进程从该中间实体取得消息。该方式广泛应用于计算机网络中。

1.7.3 管道通信

1.7.3.1 概述
  • 管道允许参与通信的两个进程按照生产者-消费者方式进行通信,生产者向管道的一端写,消费者从管道的另一端读。
  • 若数据被读空,则读进程被阻塞,直至写进程网管道中写入新数据,再将读进程唤醒;若管道被写满,则写进程被阻塞,直至读进程读出数据集,然后再将写进程唤醒。
  • 管道必须提供互斥、同步和确定双方的存在以协调双方的通信。
  • 管道大小固定,从而避免了像普通文件那样的不加检验的增长。
  • 管道只能由创建进程访问,由于管道是一个特殊文件,而子进程又会继承父进程的打开文件,因此子进程也继承父进程创建的管道,子进程也可借此与父进程进行通信。
  • 管道读取数据是一次性操作,数据一旦被读取,便会被释放。
  • 管道只能进行单向通信。若父进程子进程想要进行双向通信,则需要创建两个管道。

管道的大小通常为内存的一页。

【操作系统·考研】进程与线程_第6张图片

1.7.4 共享文件(补充)

1.7.4.1 概述

利用OS提供的文件共享功能实现进程间的通信。这时,也需要信号量来解决文件共享操作中的同步&互斥问题。

进程与程序的区别:进程是动态的,程序是静态的。

单处理系统中,若同时存在10个进程,则最多有9个进程处于就绪态,1个处于运行态,也存在一种可能–死锁,导致10个进程全部处于阻塞态。

程序的封闭性:进程的执行结果只取决于进程本身,不受环境影响,进程的执行速度并不会对其结果产生影响。

进程的最大数目取决于内存的大小。

在一个多道系统中,若就绪队列非空,则就绪进程数目的多少并不会影响到处理机的效率,相反,如果就绪队列为空,则会使处理机的效率下降。


2.线程

2.1 概述

  • 线程≈轻量级进程。它是一个基本的CPU执行单元,也是程序执行流的最小单元。
  • 线程是进程中的一个实体,是被系统独立调度和分派的基本单位。
  • 线程由线程ID+程序计数器+寄存器集合+堆栈组成。
  • 线程自己不拥有系统资源,只拥有一丢丢在运行中必不可少的资源,但它可以与同进程下的其他线程共享进程做拥有的全部资源。
  • 同一进程中的若干线程可以并发执行。
  • 线程也有就绪、运行、阻塞三种基本状态。
  • 进程是系统分配资源的最基本单位,线程是处理机调度的最基本单位。

【操作系统·考研】进程与线程_第7张图片

线程控制块(TCB):

每个线程都会配置一个TCB,用于记录控制和管理线程的信息。

组成
  • 线程标识符。
  • 一组寄存器,包括PC、状态寄存器、通用寄存器等。
  • 线程运行状态,用于描述线程正处于何种状态。
  • 优先级。
  • 线程专有存储区,用于在线程切换时保存现场。
  • 堆栈指针,用于过程调用时保存局部变量&返回地址等。

【操作系统·考研】进程与线程_第8张图片

同一进程中的所有线程共享进程的地址空间和全局变量。每个线程都可以访问地址空间中的任意一个地址单元,因此,一个线程可以读写甚至清除另一线程的堆栈。

2.2 特点

  1. 线程是一个轻型实体,每个线程都有一个唯一的标识符和一个线程控制块。线程控制块中记录了线程执行的寄存器和栈等现场状态。
  2. 不同的线程可以执行相同的程序,即同一个服务程序可以被不同的用户调用时,OS将会为它们创建不同的线程。
  3. 同一进程内的所有线程共享该进程所拥有的全部资源。
  4. 线程是处理机的独立调度单位,多个线程是可以并发执行的。
  5. 一个线程被创建后便开始了它的生命周期,它将经历就绪态、阻塞态、运行态等各种状态的变化。

2.3 状态

  1. 就绪态:线程已具备各种执行条件,只需要再获得CPU便可立即运行。
  2. 运行态:线程已获得CPU并正在运行。
  3. 阻塞态:线程在运行过程中阴某事件受阻而处于暂停状态。

2.4 状态转换

(同进程·状态转换)

2.5 线程控制

2.5.1 线程创建

用户程序启动时,通常仅有一个称为“初始化线程”的线程在工作,它主要负责创建新线程。创建新线程时,将调用一个创建线程的函数,并提供相应的参数,如指向县城主程序的入口指针,堆栈大小、线程优先级等。线程执行完成后,将返回一个线程标识符。

2.5.2 线程终止

当一个线程完成了自己的任务或遇到异常而被要求强制终止时,将由终止线程调用相应的函数执行终止操作。但是有些线程(如系统线程)将无休止地运行下去。
通常,执行了终止函数的线程只会终止运行,并不会是否其占有的资源,只有执行了分离函数后,该线程才会与占用的资源分离,资源才能被其他线程使用。我们也可以使处于终止而未分离状态下的线程重新恢复运行。

2.6 线程的实现

【操作系统·考研】进程与线程_第9张图片

2.6.1 用户级线程(User-Level Thread,ULT)

2.6.1.1 概述

线程管理的工作全权交由应用程序在用户空间负责,内核意识不到线程的存在。
通常应用程序都是从单线程开始,然后在运行过程中可以通过调用线程库中的派生例程创建一个在相同进程中运行的新线程。
【操作系统·考研】进程与线程_第10张图片

线程库
实现方法:

  • 在用户空间中提供一个没有内核支持的库,这种库的所有代码+数据结构都将存储在用户空间中。这意味着调用该库中的一个函数只会导致该用户空间中的一个本地函数的调用。
  • 实现由OS直接支持的内核级的一个库,这种库的所有代码+数据结构都将位于内核空间。调用库中的一个API函数通常会导致对内核的系统调用。

目前三种主流的线程库:POSIX Pthreads、Windows API、Java。

POSIX Pthreads能够提供用户级或内核级的库。
Windows API是Windows OS的内核级线程库。
Java线程API则允许在Java程序中直接创建和管理线程。由于JVM实例运行在宿主OS之上,因此,其线程API通常依赖于宿主OS的线程库来实现,比如在Windows平台上的Java线程则采用Windows API线程库实现,在类UNIX系统中则采用POSIX Pthreads 线程库来实现。

2.6.1.1 优点
  1. 线程切换不需要转换到内核,节省了模式切换的开销。
  2. 调度算法可以是进程专有的,不同进程可依据不同的调度算法进行线程调度。
  3. ULT的实现与OS平台无关,对线程的管理属于用户程序的一部分。
2.6.1.2 缺点
  1. 当一个线程发起系统调用时,该进程内的全部线程都将被同时阻塞。
  2. 不能发挥多处理器的优势,内核每次分配给一个进程一个CPU,因此进程中只能有一个线程运行。

ULT不需要OS的支持,与OS平台无关,可以在任何OS上运行。

2.6.2 内核级线程(Kernel-Level Thread,KLT)

2.6.2.1 概述

无论是系统线程还是用户线程都将交由OS内核管理。线程管理的所有工作均由OS内核实现。
内核空间会为每一个KLT设置一个TCB,内核会根据TCB对KLT进行管理。
【操作系统·考研】进程与线程_第11张图片

2.6.2.2 优点
  1. 能发挥多处理机的优势,内核能够调度同一进程内的若干线程并行执行。
  2. 若进程中的一个线程被阻塞,则处理机可调度其他线程继续运行。
  3. 内核支持的线程具有较小的数据结构和堆栈,线程切换比较快,开销也小。
  4. 内核本身也可采用多线程的技术,可以提高系统的执行速度和效率。
2.6.2.3 缺点
  1. 同一进程中的线程切换,需要从用户态转至内核态中进行。这是因为用户进程的线程在用户态运行,而线程调度和管理是在内核中实现的。

KLT的调度是在内核中由OS负责调度的。

2.6.3 组合方式

2.6.3.1 概述
  • 内核支持多个KLT的建立、调度与管理,同时用户程序也支持建立、调度与管理多个ULT。
  • 一些KLT对应多个ULT,这是ULT通过时分多路复用实现的。
  • 同一进程中的多个线程可在多处理机上并行运行,其中一个被阻塞了不会影响到其他线程。

【操作系统·考研】进程与线程_第12张图片

2.6.3.2 优点

ULT的优点 ∪ KLT的优点
2.6.3.3 缺点

线程包含CPU线程,可以独立执行程序。

多线程与多任务的区别:
多线程:针对于一个程序而言,代表一个程序可执行的线程个数,而每个线程可以完成不同的任务。
多任务:针对于OS而言,代表OS可同时执行的程序的个数。


3.进程与线程的对比

3.1 调度

无线程的OS中,资源分配和调度的基本单位是进程。进程每次切换都将进行上下文切换,开销很大。
有线程的OS中,线程则是调度的基本单位,其切换代价远远低于进程切换。在同一进程中,进程的切换不会引起线程的切换,而线程由一个进程切换到另一个进程在时,则会引起进程切换。

3.2 并发性

在引入线程的OS中,不同进程之间可以并发执行,同一进程或不同进程的若干线程之间同样可以并发执行。这提高了系统资源的利用率和系统的吞吐量。

3.3 拥有资源

进程是资源分配的最基本的单位。线程不拥有系统资源,仅有一丢丢确保自己可正常运行的资源,线程可以访问其宿主进程的全部资源,同属于同一进程的线程共享同一个地址空间。

3.4 独立性

每个进程都拥有一个独立的地址空间和资源,除了全局变量外,其他资源将不允许其他进程访问。进程内的线程对其他进程不可见。同一进程中的多个线程共享地址空间和资源。

3.5 系统开销

进程切换的开销大于线程切换。进程切换设计上下文的切换,而线程切换只需保持和设置寄存器的内容。同一进程内的多个线程间的通信非常容易,因为它们共享同一个地址空间和资源,它们甚至不需要OS的干预。

3.6 支持多处理机系统

对于单线程进程,进程只能运行在一个处理机上;对于多线程进程,可将进程中的若干线程分配到若干处理机上运行。


4.多线程模型

【操作系统·考研】进程与线程_第13张图片

4.1 多对一模型

4.1.1 概述

将多个ULT映射到同一个KLT。
线程调度和管理在用户空间完成,KLT需要访问内核时,才会被映射为一个KLT上,每次只允许一个ULT进行映射。
【操作系统·考研】进程与线程_第14张图片

4.1.2 优点

  1. 线程管理是在用户空间内完成的,因而效率比较高。

4.1.3 缺点

  1. 如果一个线程被阻塞,则整体被阻塞。
  2. 在任何时候都只能有一个线程去访问内核,多个线程不能同时再处理机上运行。

4.2 一对一模型

4.2.1 概述

将每一个ULT映射到一个KLT。
【操作系统·考研】进程与线程_第15张图片

4.2.2 优点

  1. 当一个线程被阻塞后,处理机依旧可以调度其他线程运行。

4.2.3 缺点

  1. 每当创建一个ULT,就需要相应地创建一个KLT,开销较大。

4.3 多对多模型

4.3.1 概述

将n个ULT映射到m个KLT上。(要求n ≥ m)
【操作系统·考研】进程与线程_第16张图片

4.3.2 优点

  1. 多对1模型∪1对1模型
  2. 既克服了多对1模型的并发度不高的缺点,又克服了1对1模型 的一个ULT占用太多KLT而开销太大的缺点。

你可能感兴趣的:(考研,操作系统,考研,操作系统)