操作系统——2.并发与进程

文章目录

  • 第二章 并发与进程
    • 2.1 进程的概念
    • 2.2 操作系统为控制程序所建立的数据结构
    • 2.3 操作系统对进程的控制
    • 2.4 线程
    • 2.5 进程调度
    • 2.6 实时系统与实时任务调度
    • 2.7 并发控制
    • 2.8 互斥与同步的解决策略
    • 2.9 生产者/消费者问题
    • 2.10 读者、写者问题
    • 2.11 进程间的通信
    • 2.12 进程死锁

第二章 并发与进程

2.1 进程的概念

★ 进程
一个正在执行的程序、正在运行的程序的一个实例、由处理器执行的一个实体
进程 = 进程控制块(PCB) + 程序段 + 数据段 + 栈

  • 引入目的:
    使多道程序能够正确地并发执行
  • 进程的两个基本属性:
    – 拥有资源的独立单位:一个进程包括一个保存进程映像的虚地址空间,拥有对资源的控制或所有权。
    – 调度/执行的基本单位:一个具有状态和优先级,可被被操作系统调度并分派的实体。

★ 基本特征

  • 动态性:(本质特性) 一个正在计算机上执行的程序实例,存在生命周期
  • 并发性:(重要特性) 任何进程都可以同其他进程一起向前推进
  • 独立性:各进程的地址空间相互独立,除非采用进程间通信手段
  • 异步性:按各自独立的、不可预知的速度向前推进
  • 结构性

★ 进程的状态转换

  • 就绪状态:进程在内存,已分配到除CPU之外的所有必要资源,准备执行
  • 执行状态:进程已获得CPU,其程序正在执行。
  • 阻塞状态:正在执行的进程由于需要等待某个事件发生而暂时无法继续执行。
  • 新建状态:OS已完成为创建一个进程所必要的工作,但进程自身还未进入主存。
  • 终止状态:进程完成或发生错误,其表格和其他信息暂时保留。
  • 挂起状态:进程交换到外存,不再参与CPU的竞争。<—> 对换技术
  • 就绪/挂起:进程在外存,只要调入内存并获得CPU即可执行
  • 阻塞/挂起:进程在外存,等待事件
\ 操作系统——2.并发与进程_第1张图片
进程挂起的原因:进程全部阻塞,处理机空闲;系统负荷过重,内存空间紧张;操作系统的需要,操作系统可能需要挂起后台进程或一些服务进程,或某些可能导致系统故障的进程;终端用户的请求;父进程请求。

2.2 操作系统为控制程序所建立的数据结构

内核的概念:一些与硬件紧密相关、基本的、公共的、运行频率较高的模块,以及关键性数据结构等常驻内存,便于提高操作系统运行效能的这部分软件,称为操作系统的内核。

★ 操作系统内核的功能

  • 资源管理功能:进程管理、存储管理、I/O设备管理
  • 支撑功能:中断处理、时钟管理、原语操作、统计监测功能

★ 操作系统控制结构
操作系统构造并维护它所管理的每个实体的信息表,一般有4种不同类型的表:内存、I/O、文件和进程。

\ 操作系统——2.并发与进程_第2张图片

★ 进程控制块

进程控制块的作用: 进程存在的唯一标志;PCB常驻内存。

进程控制块中的信息

  • 进程标示符:唯一地标识一个进程。内部、父、用户标识符
  • 处理机状态信息:通用寄存器、指令计数器、程序状态字、用户栈指针
  • 进程控制信息:进程状态、进程优先级、进程调度所需的其他信息、事件
  • 其他信息:程序和数据的地址、进程同步和通信机制、资源清单、链接指针

进程控制块的组织方式

  • 索引方式、
  • 链接方式(单一队列、多级队列)

2.3 操作系统对进程的控制

2.3.1 进程的创建

引起创建进程的事件

  • 用户登录、为新的作业创建进程、操作系统因为提供一项服务而创建、由现有的进程派生

创建进程的步骤:

  • 给新进程分配一个唯一的进程标识符
  • 为进程分配空间、初始化进程控制块
  • 建立链接,将之插入就绪或就绪/挂起链表
  • 建立或扩充其它数据结构

2.3.2 进程的撤销

引起进程终止的事件

  • 正常结束、异常结束(越界错误、保护错、非法指令、特权指令错、运行超时、等待超时、算术运算错、I/O故障)、外界干预(程序员kill进程、父进程终止、父进程请求)

进程终止的步骤

  • 根据被终止进程的标识符找到其PCB,读出该进程的状态
  • 若该进程为执行状态,则终止其执行,调度下一个就绪进程执行
  • 若该进程还有子孙进程,还应将其所有子孙进程予以终止
  • 将该进程所拥有的全部资源,或者归还给其父进程,或者归还给系统
  • 将被终止进程的PCB从所在队列中移出

2.3.3 进程的阻塞

引起阻塞的事件

  • 请求系统服务而得不到满足、启动某操作而需同步、新数据尚未到达、无新工作

进程阻塞的步骤

  • 进程通过调用阻塞原语block( )把自己阻塞
  • 将PCB中的状态由“执行”改为“阻塞”,并将PCB插入阻塞队列
  • 调度程序将处理机分配给另一就绪进程,并进行切换

2.3.4 进程的唤醒

  • 由有关进程调用唤醒原语wakeup( )将等待该事件的进程唤醒
  • 被阻塞的进程从等待该事件的阻塞队列中移出
  • 将其PCB中的现行状态由阻塞改为就绪
  • 将该PCB插入到就绪队列中

2.3.5 进程的挂起

引起挂起suspend( )的事件

  • 内存资源紧张、进程全部阻塞,CPU空闲
    程序挂起的步骤:
  • 检查被挂起进程的状态,若处于就绪状态,便将其改为就绪/挂起
  • 对于处于阻塞状态的进程,则将之改为阻塞/挂起
  • 将进程移出内存

2.3.6 进程的激活

  • 将进程从外存处于挂起状态的进程调入内存,激活原语active()
  • 检查该进程的现行状态: 若是就绪/挂起,便将之改为就绪;若为阻塞/挂起,便将之改为阻塞

2.3.7 进程切换

概念:调度另一个就绪进程占用处理器执行

何时发生:时钟中断、I/O中断、内存失效、陷阱、系统调用

进程切换的步骤:

  • 保存处理器上下文环境,包括程序计数器和其它寄存器
  • 更新当前处于运行状态进程的进程控制块
  • 将进程的进程控制块移至相应队列(就绪、阻塞等)
  • 选择另一进程执行
  • 更新其进程控制块信息
  • 恢复被选择进程的上下文环境

★ UNIX进程控制

fork():创建一个新进程。

调用格式: pid = fork()

在调用fork()之后,父进程和子进程均在下一条语句上继续运行。在子进程中返回时,pid为0;在父进程中返回时,pid为所创建的子进程的标识。

2.4 线程

2.4.1 线程的概念

概念:线程又叫轻量级进程,进程的一个实体,是系统独立调度和分派的基本单位。

优势:增加系统的并发性,减少并发执行时的时空开销。

属性

  • 除了一点必不可少的资源(如TCB、程序计数器、寄存器和堆栈)外,线程基本
    上不拥有系统的资源
  • 独立调度和分派的基本单位
  • 同一个进程中的多个线程以及不同进程中的多个线程均可并发执行
  • 同一个进程中的各线程可以共享该进程中所拥有的全部资源,如进程的地址空
    间、已打开的文件、定时器和信号量等

2.4.2 进程与线程的关系

\ 操作系统——2.并发与进程_第3张图片

2.4.3 多线程并发

线程的基本状态:

  • 就绪状态、执行状态、阻塞状态

线程的基本操作:

  • 派生:线程可以由进程或线程所派生
  • 阻塞:等待某事件,并释放处理机
  • 解除阻塞:等待的事件发生,状态变成就绪,插入就绪队列,等待调度执行。
  • 结束:执行完毕,释放其私有资源

2.4.4 线程的类型

  • 用户级线程:操作由应用程序完成;操作系统不知道线程存在,仍以进程为调度单位。
  • 内核级线程:操作由系统内核完成,以线程为调度单位。
  • 混合线程:操作由应用程序完成,多个用户级线程被影射到一个或较少的某些内核级线程
操作系统——2.并发与进程_第4张图片

2.5 进程调度

2.5.1 调度的目标和原则
目标:防止饥饿、提高处理器的利用率、提高系统吞吐量、减少响应时间
原则:用户的需求(响应时间快、平均周转时间短、满足截止时间)、系统的需求(吞吐量大、CPU利用率高、各类资源的平衡使用、公平性、优先权)

2.5.2 调度的类型
长程调度(高级调度、作业调度):

  • 决定外存上处于后备队列中的哪个作业调入内存
  • 为它们创建进程、分配必要的资源
  • 将新创建的进程排在就绪队列(就绪/挂起)上,等待短程(中程)调度。

中程调度(中级调度)

  • 对换功能的一部份,用以提高内存的利用率和系统的吞吐量。
  • 内存紧张时,选择一个进程换出到外存(换出)。
  • 内存充裕时,从外存选择一个挂起状态的进程调度到内存(换入)。
  • 只有支持进程挂起的操作系统才具有中程调度功能

短程调度(进程调度、低级调度)

  • 决定就绪队列中的哪个进程应获得处理器
  • 运行频率最高
  • 现代操作系统几乎都具有短程调度功能

2.5.3 一些相关的基本概念

  • 响应时间:从用户通过键盘提交一个请求开始,直至系统首次产生响应为止的时间。
    响应时间 = 输入传送时间 + 处理时间 +响应传送时间
  • 周转时间:从作业被提交给系统开始,到作业完成为止的时间。
    = 驻外存等待调度时间 + N *(驻内存等待调度时间+执行时间+阻塞时间)
  • 带权周转时间:作业的周转时间与系统为它提供服务的时间之比。
  • 截止时间:某任务必须开始执行的最迟时间,或必须完成的最迟时间。一般用于实时系统。
  • 系统吞吐量:在单位时间内系统所完成的作业数。

2.5.4 调度的分类
按是否剥夺当前进程来分:非剥夺方式、剥夺方式
按被调度进程的状态来分:长程调度、中程调度、短程调度

2.5.5 常见的调度算法
操作系统——2.并发与进程_第5张图片

2.6 实时系统与实时任务调度

实时系统的基本要求:
可确定性、可响应性、用户控制、可靠性、失效弱化

实时任务的分类
按截止时间分:硬实时任务、软实时任务
按周期性分:周期性任务、非周期性任务

实时调度的目标
使硬实时任务在其规定的截止时间内完成(或开始),同时尽可能使软实时任务也能在规定的截止时间内完成(或开始)。

★ 常见的实时调度算法
(1) 基于时间片轮转的调度 秒级,用于分时、一般实时处理系统
(2) 基于优先级的非抢占调度 百毫秒~数秒级,用于多道批处理系统
(3) 基于优先级的抢占点抢占调度 几毫秒~几十毫秒,一般实时系统
(4) 立即抢占式调度 毫秒级,苛刻的实时系统
(x) 限期(deadline)调度: 最早截止时间优先调度算法(EDF)
最低松弛度优先调度算法(LLF)
速度单调调度算法(RMS)
松弛度=完成截止时间-剩余执行时间-当前时间

2.7 并发控制

★ 相关概念
临界资源:一次仅允许一个进程访问的资源为临界资源
临界区:把在每个进程中访问临界资源的那段代码称为临界区。临界区是一段代码,在这段代码中进程将访问临界资源,当另外一个进程已经在这段代码中运行时,这个进程就不能在这段代码中执行。
死锁:两个或两个以上的进程相互等待导致都不能执行
互斥:当一个进程在临界区访问临界资源时,其他进程不能进入该临界区访问共享资源
竞争:多个进程读写一个共享数据时依赖它们执行的相对时间
饥饿:一个进程已经完全具备了执行的条件,但是得不到CPU资源

★ 进程间的制约关系
间接制约:资源共享–>互斥
直接制约:进程合作–>同步

★ 临界区使用原则(互斥条件)

  • 空闲让进:如临界区空闲,则有进程申请就立即进入。
  • 忙则等待:每次只允许一个进程处于临界区。
  • 有限等待:保证进程在有限时间内能进入临界区。
  • 让权等待:进程在临界区不能长时间阻塞等待某事件。

2.8 互斥与同步的解决策略

★ 软件方法
在进入区设置和检查一些标志来标明是否有进程在临界区。若已有进程在临界区,则在进入区通过循环检查进行等待,进程离开临界区后则在退出区修改标志。
始终存在忙等问题。
通常能实现两个进程的互斥,很难控制多个进程的互斥。

★ 硬件方法
屏蔽中断:避免进程切换,实现互斥访问。
专用机器指令:设计专门的机器指令用于保证动作的原子性,如Test&Set、Exchange。
硬件方法支持多处理机和多临界区,但存在忙等、饥饿和死锁的现象。

★ 信号量方法
信号量实现进程互斥的基本原理

  • 两个或多个进程可以通过传递信号进行合作,可以迫使进程在某个位置暂时停止
    执行(阻塞等待),直到它收到一个可以“向前推进”的信号(被唤醒)。
  • 信号量s一个域为整型,另一个域为队列(等待该信号量的阻塞进程们)

信号量的定义
操作系统——2.并发与进程_第6张图片
信号量的两个原子操作
操作系统——2.并发与进程_第7张图片

信号量的类型

  • 互斥信号量:用于申请或释放资源的使用权,初始值为1。范围: [ -(n-1), 1 ] 。
  • 资源信号量:用于申请或归还资源,表示某资源的可用数目。范围: [ m-n, m]

n个进程共享临界资源: -(n-1)≤s.count ≤1

★ 管程

管程是一个程序设计语言结构,采用了集中式的进程同步方法,提供了与信号量同样的功能,但更易于控制。一个管程定义了一个数据结构和能为并发进程所执行(在该数据结构上)的一组操作,这组操作能同步进程和改变管程中的数据。(C. A. R. Hoare & Per Brinch Hansen)
管程是由一个或多个过程、一个初始化序列和局部数据组成的软件模块。主要特点:

  • 局部数据变量只能被管程的过程访问,任何外部过程都不能访问。
  • 一个进程通过调用管程的一个过程进入管程。
  • 在任何时候,只能有一个进程正在管程执行,调用管程的任何其它进程都被阻塞,以等待管程可用。

2.9 生产者/消费者问题

  • 应先申请资源信号量,再申请互斥信号量,顺序不能颠倒。
  • 同一进程中的多对wait和signal语句可以嵌套,也可以交叉。
  • 对于同一个信号量的wait与signal操作,既可以出现在同一个进程中,也可以出现在不同进程中。
  • 对任何信号量的wait与signal操作必须配对。
  • 在进入临界区前必须先执行wait操作,退出临界区后必须执行signal操作。对于同一信号量而言,既有可能先执行wait操作,也有可能先执行signal操作。

★ 1个生产者、2个消费者被连接到大小为N的缓冲区上,2个消费者分别消费不同资源

  • 盘子是一互斥资源,故设置互斥信号量mutex(1)
  • 爸爸、儿子因为桔子的放入与取出而同步,设置资源信号量orange(0)
  • 爸爸、女儿因为苹果的放入与取出而同步,设置资源信号量apple(0)
  • 爸爸、儿子、女儿因为共享盘子,设置资源信号量empty(N)

★ 2个生产者、2个消费者被连接到大小为1的缓冲区上,2个生产者分别生产不同的资源,2个消费者也分别消费不同的资源

  • 盘子是一互斥资源,故设置互斥信号量plate(1)
  • 爸爸、女儿因为苹果的放入与取出而同步,设置资源信号量apple(0)
  • 妈妈、儿子因为桔子的放入与取出而同步,设置资源信号量orange(0)

★ 2个生产者、1个消费者被连接到大小为2的缓冲区上,2个生产者分别生产不同的资源,当两种资源同时存在时消费者才能进行消费

  • 盘子是一互斥资源,故设置互斥信号量mutex(1)
  • 盘子中是否可以放入苹果,设置信号量empty_apple(1)
  • 盘子中是否可以取出苹果,设置信号量apple(0)
  • 盘子中是否可以放入桔子,设置信号量empty_orange(1)
  • 盘子中是否可以取出桔子,设置信号量orange(0)

★ 1个生产者、2个消费者被连接到大小为1的缓冲区上,每个数据被消费两次才结束生命周期,消费者可以同时消费同一数据

  • 爸爸是否欣赏过,设置资源信号量empty_dad(1)
  • 爸爸是否可以欣赏,设置资源信号量full_dad(0)
  • 妈妈是否欣赏过,设置资源信号量empty_mom(1)
  • 妈妈是否可以欣赏,设置资源信号量full_mom(0)

2.10 读者、写者问题

允许多个读者进程可以同时读数据;
不允许多个写者进程同时写数据,即只能互斥写数据;
若有写者进程正在写数据,则不允许读者进程读数据——互斥读写。

★ 读者优先
一旦有读者正在读数据,则允许随后的读者进入读数据。只有当全部读者退出,才允许写者进入写数据。导致写者饥饿

  • wsem:互斥信号量,用于Writers互斥Writers和Readers,以及第一个Reader互斥Writers。(1)
  • readcount:统计同时读数据的Readers个数(int型/0)
  • mutex:对变量readcount互斥算术操作(1)

★ 公平优先
读者、写者的执行顺序与到达顺序严格一致。

  • wsem:互斥信号量,用于…
  • readcount:统计同时读数据的Readers个数(int型/0)
  • mrc:对变量readcount互斥算术操作(1)
  • wrsem:互斥信号量,确定Writer 、Reader请求顺序(1)

★ 写者优先
只要有一个写者申请写数据,则不再允许新的读者进入读数据。解决了写者饥饿问题,但降低了并发程度,系统的并发性能较差。

  • rsem:互斥信号量,当至少有一个写者申请写数据时互斥新的读者进入读数据(1)
  • wsem:互斥信号量,用于…(1)
  • readcount:统计同时读数据的Readers个数(int/0)
  • writecount:用于控制rsem信号量(int/0)
  • mrc:对变量readcount互斥算术操作(1)
  • mwc:对变量writecount互斥算术操作(1)

2.11 进程间的通信

进程通信:进程之间的信息交换

★ 共享存储区

操作系统——2.并发与进程_第8张图片

★ 消息传递

两条通信原语:Send(destination,message)、Receive(source,message)

三种同步方式:

  • 阻塞发送,阻塞接收;
  • 不阻塞发送,阻塞接收;
  • 不阻塞发送,不阻塞接收

邮箱:不不限制进程数,允许多个发送进程向邮箱发送消息,同时,也允许多个接收进程从邮箱接收消息

利用消息传递实现互斥

  • 共享一个邮箱,初态仅包含一条空消息;
  • 采用“不阻塞发送,阻塞接收”方式传递消息;
  • 若邮箱中存在一条消息,则允许一个进程进入临界区。
  • 若邮箱为空,表明有一个进程位于临界区,其它试图进入临界区的进程必须阻塞。
  • 只要保证邮箱中最多只有一条消息,就能保证只允许一个进程进入临界区,从而实现进程互斥使用临界资源。

利用消息传递解决生产者/消费者问题

  • 使用capacity条消息,其作用类似于缓冲区的大小;
  • capacity条消息的初始状态为“空”消息,类似于缓冲区的初始状态为空(未填充生产数据);
  • 生产者生产一条数据后,取一条“空”消息,并发送回一条填充了数据的消息;
  • 消费者消费一条数据后,取一条填充了数据的消息,并发送回一条“空”消息;
  • 若生产者速度快于消费者消速度,则因无“空”消息可用而阻塞;
  • 若消费者速度快于生产者消速度,则因无填充了数据的消息可用而阻塞。

2.12 进程死锁

★ 死锁的概念
多个进程因为竞争资源或执行时推进的顺序不当,或相互通信出现永久阻塞现象,如果没有外力作用,这种现象将永远保持下去。

★ 产生死锁的原因

  • 资源不足导致的资源竞争
  • 并发执行的顺序不当

★ 产生死锁的充分必要条件

  • 互斥、占有且等待、非剥夺条件是死锁产生的必要条件,但不是充分条件。
  • 循环等待条件实际上是互斥、占有且等待、非剥夺条件的可能导致的结果。
  • 只要系统出现循环等待,则一定出现死锁。
  • 互斥、占有且等待、非剥夺条件、循环等待条件构成了死锁产生的充分必要条件。

★ 解决死锁的方法

  • 预防 :添加限制条件,破坏产生死锁的条件(四个必要条件中的一两个)
  • 避免 :动态检查,防止系统进入不安全状态。银行家算法
  • 忽略 :鸵鸟策略
  • 检测解除:允许死锁,但(不)定期检测死锁并解除
     死锁检测:(死锁定理:)状态S为死锁状态的充要条件是:当且仅当S状态的资源分配图是不可完全简化的。
     死锁解除:撤销进程、资源剥夺、进程回退

★ 安全性算法
操作系统——2.并发与进程_第9张图片

★ 银行家算法
设计思想:当用户申请一组资源时,系统必须做出判断:如果把这些资源分出去,系统是否还处于安全状态。若是,就可以分配这些资源;否则,暂时不分配,阻塞进程。
操作系统——2.并发与进程_第10张图片
银行家算法的使用:
(1)首先根据安全性算法判断初始时刻系统是否处于安全状态,如果是,则继续往下进行。
(2)当某进程请求资源时,根据银行家算法判断是否对其分配资源。
(3)循环执行(2)。直到所有进程都顺利完成。

★哲学家就餐问题

方案一:为餐叉编号;就餐前,先取用编号较低的餐叉,再取用编号较高的餐叉;就餐毕,先放下编号较高的餐叉,再放下编号较低的餐叉。

方案二:为哲学家编号;奇数号的哲学家必须首先拿左边的餐叉;偶数号的哲学家必须首先拿右边的餐叉。

方案三:引入一个餐厅服务生,哲学家必须经过他的允许才能拿起餐叉;最多允许4个哲学家同时进食。

方案四:仅当哲学家的左右手筷子都拿起时才允许进餐。多个临界资源,要么全部分配,要么一个都不分配。

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