[操作系统OS]第六章: 进程和线程

一、进程的基础概念

定义

组成

一个进程应该包括以下内容:

  • 程序的代码
  • 程序处理的数据
  • 程序计数器的值,指示下一条将运行的指令
  • 一组通用的寄存器的当前值,堆,栈
  • 一组系统资源(如打开的文件)

总之,进程包含了正在运行的一个程序的所有状态信息。
程序是产生进程的基础,程序的每次运行构成不同的进程。进程是程序功能的体现,通过多次执行,一个程序可对应多个进程。通过调用关系,一个进程可以包括多个程序。
进程是动态的,程序是静态的。程序是有序代码的集合,进程是程序的执行,进程可以有内核态和用户态。进程是暂时的,程序是永久的。进程是一个状态变化的过程,程序可以长久保存。进程和程序的组成不同,进程的促成包括程序、数据和进程控制块(进程状态信息)。

特点

动态性:可动态地创建,结束进程
并发性:进程可以被独立调度并占用处理机运行(并发是一段时间内有多个程序执行,并行是同一个时刻有多个程序执行)
独立性:不同进程的工作不互相影响
制约性:因访问共享数据/资源或进程间同步而产生制约

操作系统为每一个进程都维护了一个PCB(进程控制块:描述进程的数据结构),用来保存与该进程有关的各种状态信息。


二、进程的控制

进程控制结构

进程控制块PCB:操作系统管理控制进程运行所用的信息集合。
操作系统用PCB来描述进程的基本情况以及运行变化的过程,PCB是进程存在的唯一标志。
进程的创建:为该进程创建一个PCB
进程的终止:回收这个进程的PCB
进程的组织管理:通过对PCB的组织管理来实现
PCB含有以下三大类信息:

  1. 进程标识信息:比如进程的标识,进程的产生者标识(父进程标识),用户标识
  2. 处理机状态信息保存区:保存进程的运行现场信息
  • 用户可见寄存器:用户程序可以使用的数据、地址等寄存器
  • 控制和状态寄存器:程序计数器,程序状态字
  • 栈指针:过程调用、系统调用、中断处理和返回时需要用到该指针
  1. 进程控制信息:操作系统对进程进行管理控制,让进程处于什么状态的信息
  • 调度和状态信息:用于操作系统调度进程并占用处理机使用
  • 进程间通信信息:为支持进程间的与通信相关的各种标识、信号、信件等,这些信息存在接受方的进程控制块中
  • 存储管理信息: 包含有指向本进程映射存储空间的数据结构
  • 进程所用资源: 说明由进程打开、使用的系统资源,如打开的文件等
  • 有关数据结构的连接信息:进程可以连接到一个进程队列中,或者连接到相关的其他进程的PCB

组织方式
链表:同一状态的进程其PCB成一链表,多个状态对应多个不同的链表,各状态的进程形成不同的链表,例如就绪链表、阻塞链表
索引表:同一状态的进程归入一个index表(由index指向PCB),多个状态对应多个不同的index,各状态的进程形成不同的索引表,例如就绪索引表,阻塞索引表。

不同的操作系统可能会有不同的PCB组织方式。


三、进程的动态特点(进程状态)

进程的生命期管理

生命周期为:

  • 进程创建
  • 进程运行
  • 进程等待
  • 进程唤醒
  • 进程结束

进程创建和运行

引起进程创建的3个主要事件:

  • 系统初始化的时候会创建第一个线程(init进程)
  • 用户请求创建一个新进程
  • 正在运行的进程执行了创建进程的系统调用

内核选择一个就绪的进程,让它占用处理机并执行。进程创建后并不能马上被运行,就会进入等待状态。

进程等待

引起进程等待的原因:

  • 请求并等待系统服务,无法马上完成
  • 启动某种操作,无法马上完成
  • 需要的数据没有到达

进程只能自己阻塞自己,因为只有进程自己知道什么时候需要等待什么事件的发生。

进程唤醒

唤醒的原因:

  • 被阻塞的进程需要的资源可被满足
  • 被阻塞的进程等待的事件到达
  • 将该进程的PCB插入到就绪队列

进程只能被操作系统或者其他进程唤醒。

进程结束

进程结束的情况:

  • 正常退出(自愿的)
  • 错误退出(自愿的)
  • 致命错误(强制性的)
  • 被其他进程所杀(强制性的)

进程的状态变化模型

进程的三种基本状态:进程在生命结束前处于且仅处于三种基本状态之一,不用系统设置的进程状态数目不同。

  • 运行状态(running):当一个进程正在处理机上运行时
  • 就绪状态(ready):一个进程获得了除处理机之外的一切所需资源,一旦得到处理机即可运行
  • 等待状态(或阻塞状态blocked):一个进程正在等待某一事件而暂停运行时的状态,如等待资源,等待IO完成

如果还需要细分,则还可以拥有以下基本状态:

  • 创建状态(new):一个进程正在被创建,还没被转到就绪状态之前的状态
  • 结束状态(exit):一个进程正在从系统中消失时的状态,这是因为进程结束或由于其它原因所导致(PCB独占,等到PCB消失后,进程就彻底消失)


进程挂起

进程在挂起状态时,意味着进程没有占用内存空间,处于挂起状态的进程映像在磁盘上。

挂起状态有两种:

  • 阻塞挂起状态(blocked-suspend):进程在外存并等待某事件的出现(已经是阻塞状态再被挂起)
  • 就绪挂起状态(ready-suspend):进程在外存,但只要进入内存,即可运行(进入内存就会变成就绪状态,本身就是就绪状态再被挂起)

挂起(Suspend):把一个进程从内存转到磁盘上
可能触发挂起的情况:

  • 阻塞到阻塞挂起:没有进程处于就绪状态或者就绪进程需要更多的内存资源,就会进行这种转换,以提交新进程或者运行就绪进程
  • 就绪到就绪挂起:当高优先级阻塞(系统认为会很快就绪的)进程和低优先级就绪进程冲突时,系统会挂起低优先级就绪进程,还是看进程优先级的
  • 运行到就绪挂起:对于抢先式分时系统,当有高优先级阻塞挂起进程因为事件而变成 就绪挂起时,系统可能会把正在运行的进程转到就绪挂起状态,注意是可能

那么在外存中的状态转换为:

  • 阻塞挂起到就绪挂起:当阻塞挂起的进程因为相关事件出现时,系统会把阻塞挂起进程转化为就绪挂起进程(只是状态改变了)

解挂/激活(activate):把一个进程从磁盘转到内存
可能触发的情况为:

  • 就绪挂起到就绪:没有就绪进程或者挂起就绪进程优先级高于就绪进程时就会进行这种转换
  • 阻塞挂起到阻塞:当一个进程释放足够的内存时,系统会把一个高优先级的阻塞挂起进程(系统认为会很快出现所等待的事件发生) 转为阻塞进程

操作系统如何使用这些状态和PCB来管理进程?
答案就是状态队列:

  1. 状态队列是由操作系统来维护的一组队列,用来表示系统当中所有进程的当前状态
  2. 不同的状态分别用不同的队列来表示(就绪队列,各种类型的阻塞队列等)
  3. 每个进程的PCB都根据它的状态加入到相应的队列当中,当一个进程的状态发生变化时,它的PCB从一个状态队列中脱离,加入到另一个状态队列里


四、线程

随着程序功能的增多,我们需要一个实体可以并发的执行,并且实体之间也可以共享地址空间,所以线程诞生了,这个实体就是线程。
定义:进程中的一条执行流程

进程由资源管理和线程两个部分组成。
属于一个进程的线程共享进程所拥有的资源,每一个线程拥有自己的TCB(线程控制块,只负责管理线程执行流程相关的信息),线程之间可以并发执行。一个线程崩溃可能会导致其所属的所有线程崩溃。
线程同样由就绪、阻塞、执行三种基本状态,同样具有状态之间的转换关系。切换线程的时间要比进程更短,因为线程的地址通常是靠在一起的,不需要进行页表的切换,代价更小。

线程的实现

用户线程

在用户空间实现的线程机制,不依赖于操作系统,由一组用户线程库函数来完成线程的管理。

  • 不需要操作系统内核了解用户线程的存在,可用于不支持线程技术的多进程操作系统;
  • 每个进程都需要它私有的线程控制块TCB列表,来跟踪记录它各个线程的状态信息(PC/栈指针/寄存器),TCB由线程库函数来维护;
  • 用户线程的切换由线程库函数实现,无需 用户态/核心态切换,所以速度快;
  • 允许每个进程有自定义的线程调度算法。

注意:用户线程的TCB是放在用户空间中的

缺点:

  • 如果一个线程发起系统调用而阻塞,则整个进程都在等待;因为操作系统只会操作进程进行阻塞。
  • 如果一个线程开始运行,除非它主动交出CPU,否则该线程所在进程的其它线程都无法运行;因为用户线程库函数没有权限对线程进行中断操作,只有操作系统有这个权限。
  • 由于时间片分配给的是进程,所以与其它进程相比,在多线程执行时,每个线程得到的时间片较少,执行会较慢。

内核线程

在操作系统内核空间中的,由操作系统内核实现的一种线程机制,内核来完成线程的创建、中止、管理。

操作系统可以感知到内核线程,因为内核线程的PCB,TCB都存在于内核空间中,windows操作系统就是这种设计模式。切换内核线程的开销会比较大,主动切换的时候会有一次用户和内核空间切换的过程。

  • 由内核维护进程和上下文信息,也就是进程/线程控制块PCB/TCB;
  • 线程的创建/终止/切换都是通过系统调用或内核函数来实现(内核实现),所以系统开销大;
  • 在一个进程中,如果某个内核线程发起系统调用而阻塞,不会影响其它内核线程的运行;
  • 时间片分配给线程,多线程的进程能获得更多的CPU时间;
  • Windows NT/2000/XP 支持内核线程。

轻量级线程

linux系统就采用这种设计方式。它是内核支持的用户线程。一个进程可以有一个或多个轻量级进程,每个轻量级进程由一个单独的内核线程来支持。

执行起来效率会更高一些。

上下文切换

停止当前运行进程(从运行态改变成其它状态)并且调度其它进程(转变成运行态)。

  • 必须在切换之前储存许多部分的进程上下文
  • 必须能够在之后恢复它们,进程不能显示它曾经被暂停过
  • 必须快速(上下文切换非常频繁)

需要存储的信息:寄存器(PC , SP …), CPU状态等等【这些都是Context上下文】。一些时候可能会比较费时,应该尽可能避免。

当需要切换进程的时候,需要保存A的上下文信息到PCB中,然后将B进程的PCB中的上下文信息恢复到CPU中,便完成了进程的切换。其中所有的信息和硬件都紧密相连,所以这部分代码是使用汇编编写。上下文的切换同样为了执行效率的提升,采用汇编编写。
为了知道哪些进程可以切换,操作系统为活跃进程准备了PCB进程控制块,其次会将就绪的进程放在就绪队列中,等待调用。也准备了相应的等待队列,和僵尸队列(存放刚死掉但没有被父进程回收的进程)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值