计算机操作系统笔记(六)

第六章 并发程序设计

6-1 并发程序设计及其基本概念

U 顺序程序设计
M 并发程序设计的概念
U 并发程序的特征

程序是石先生算法的操作的指令序列,每个程序在处理器上执行时严格有序的,称为程序执行的内部顺序性。程序设计的一般习惯是顺序程序设计,严格的把一个具体问题的求解过程设计成一个程序或者若干严格顺序执行的程序序列,这称为程序之行的外部顺序性。

顺序程序设计的特征
程序执行的顺序性
计算环境的封闭性
计算结果的确定性
计算过程的可再现性

进程的并发执行:多道程序让多个程序同时进入内存区竞争处理器,以获得运行机会,OS运行多个进程并发执行,OS保证按照“顺序程序设计”方法编制的程序在并发执行时不受影响,如独占计算机,这些按照顺序设计思想编制的进程在OS中执行属于无关的并发进程

并发程序设计:把一个具体问题求解设计成若干个可同时执行的程序模块的方法。
特性:并发性、提高了程序的计算效率、共享性、交往性

6-2 并发进程的制约关系

与时间相关的程序设计错误:对于一组交往的并发进程,执行的速度无法相互控制,如果程序设计不当,可能出现各种与时间有关的错误。
表现一:计算结果错误
表现二:永远等待
例如机票问题、内存管理问题

进程互斥与进程同步
交互的进程在执行时必须进行制约,才能保证得到合理的结果

进程的互斥:并发进程之间因相互争夺独占性资源而产生的竞争制约关系。

进程同步:并发进程之间为完成共同任务基于某个条件来协调完成,执行先后关系而产生的协作制约关系。例如输入进程必须在输入结束之后计算进程,才能够对输入结果进行加工处理,这个次序必须严格的约定。

6-3 临界区

M 临界区的基本概念
M 临界区管理的三个要求
互斥与临界区
1.临界资源:互斥共享变量所代表的资源,即一次只能被一个进程所使用的资源
2.临界区指并发进程中与互斥共享变量相关的程序段
3.多个并发进程访问临界资源时,存在竞争制约关系
4.如果两个进程同时停留在相关的临界区内,就会出现于时间相关的错误

临界区的描述
确定临界资源
shared
确定临界区
region do
两个进程的临界区有相同的临界资源,就是相关的临界区,必须互斥进入,两个临界区不想管,进入就没有限制

临界区管理的三个要求
1.一次至多允许一个进程停留在相关的临界区
2.一个进程不能永远停留在临界区内
3.一个进程不能不能永远等待进入临界区

临界区的嵌套使用时合法的,要注意防止死锁

6-4 临界区管理实现的尝试

6-5 临界区管理实现的硬件方法

测试并建立指令

6-6 pv操作与进程互斥

U 信号量的概念
M 记录型信号量
M PV操作原语

应用PV操作解决进程互斥问题
问题的提出:TS或swap指令管理临界区,采用忙式轮询效率低,开关中断管理临界区不便交给用户程序使用。
参考:操作系统访问硬件资源时采用“请求等待”-“中断恢复方式”

信号量的构想
1.一种可动态定义的软件资源,信号量
2.核心数据结构:等待进程队列
3.信号量声明:资源报到,建立队列
4.申请资源的原语:若申请不到,调用进程入队列等待
5.归还资源的原语:若队列中有等待进程,需释放
6.信号量撤销,资源注销,撤销队列

记录型信号量的定义
一种带数值的软件资源

6-7 PV操作与进程同步

U PV操作解决进程同步的方法

进程同步:并发进程为完成共同任务基于某个条件协调执行先后关系而产生的协作制约关系,一个进程的执行等待来自其他进程的消息

解决的基本思路
定义一个信号量,其数值代表可用消息数
等待消息进程:执行P,无消息则等待
发出消息进程:执行V,有等待进程则释放

6-9 管程概述

M 管程的基本概念
U 管程与条件变量
U 管程的执行模型

P、V操作解决并发程序设计遇到的最大的问题就是程序设计的难度非常大。把PV操作分布在程序的各个部分,不利于大家去集中的思考去抽象这样一个并发程序设计的问题,容易产生各种各样的程序设计错误。

管程,利用面向对象程序设计类的概念,把相关进程中对于共享进程的访问,用一个友善的开发程序设计环境,把它封装起来。那么,显而易见,与C++中类一样,管程是若干个公共变量的说明及其访问这些公共变量的过程构成的一个程序单位

管程把分散在各个进程中互斥访问公共变量的那些临界区集中起来管理,进程的局部变量只能由那些访问管程的过程存取,使得我们的程序设计变得更加方便。但是它和C++类有一个非常大的区别,也就是说进程只能互斥地调用管程中的过程,而C++当中的函数,我们不要求互斥的调用,所以C++其实是有一个问题的,他对并发程序设计不是非常实用。

管程的基本形式
①管程的变量,不能被外部变量所访问
②它要实用的外部的过程,以及能够被外部使用的进程
③过程
④初始化的语句

管程的条件变量
管程仅仅是一个共享变量,那么管程还是关于条件变量。什么叫条件变量,条件变量说白了就叫信号量。我们前面讲过,记录型信号量是信号量的一种表现方式,那么条件变量也是信号量,只不过是信号量的另外一种实现方式,它也是一种软件资源。当管程无法继续运行时,用于阻塞管程、调用管程过程的进程,显然他需要两条原语:阻塞原语wait和释放原语signal

管程的执行模型
调用管程过程的进程在这里排队

当管程过程执行不下去时,调用管程过程的进程就要进入条件变量队列等待,那么它进了等待队列,就可以开放管程了,也就是说其他等待进入管程过程的 进程就可以进入管程过程。
还有一个问题,条件变量队列被执行signal释放操作时,显而易见,signal操作一定是在一个进程调用管程过程的过程中发出的,那么,它一旦释放了一个等待条件变量的进程之后,就会有两个进程同时停留在管程过程中,释放者和被释放者,这就违反了管程开放的准则了,那么我们就得把其中一个挂起来,让它进入等待进程队列,这个时候就出现了第三个等待进程队列。
注意,第三类等待进程队列和第1类等待进程队列都是等待调用管程过程的,它和第二类等待进程队列等待条件变量不是一样的

活儿管程执行signal的进程等待,直到被释放进程退出管程或等待另一个时间。汉森选择了二者的折中,增加了难度。

6-10 霍尔管程

U管程实现的霍尔方法
U 霍尔管程的条件变量
U 霍尔管程的程序过程

霍尔管程的实现方法:使用signal释放一个等待进程,霍尔管程让直行了signal的进程等待,直到被释放进程退出管程或等待另一个条件。

霍尔管程基于PV操作原语实现wait和signal,可以使程序过程,可以用语言机制实现霍尔管程,不需要扩展OS内核。

互斥调用霍尔管程的信号量

进程调用管程过程时,必须加上一个帽子,进入的时候它首先在低优先级的队列上排,如果没人调用管程过程的话,它就能进去,否则就得排。出来的时候,它就得开放管程,但是开放管程的时候呢,它首先得释放高优先级的队列,高优先级中没有再去,释放低优先级的队列。

霍尔管程的条件变量
具体的跟共享变量有关的等待进程队列

6-11 霍尔管程的例子

6-12 进程通信

M 进程通信的概念
U 进程直接通信
M 进程间接通信

进程通信:交往进程通过信号操作实现进程互斥和同步,这是一种低级的通信方式。可以引进高级通信方式,扩充并发进程的数据共享。

进程直接通信:发送或接受信件的进程指出信件发给谁或从谁那里接受
send(p,信件)
receive(Q,信件)

进程间接通信:发送或接收信件通过一个信箱,该信箱具有唯一标识符
send(A,信件)
receive(A,信件)

6-13 高级进程通信机制

U 基于字节流的通信规约
U 基于RPC的高级通信规约

由会话层上升到表示层,简化了程序设计的难度

基于流的进程通信
1.多个进程使用一个共享消息缓冲区
(管道、多路转接器、套接字)
2.一些进程往消息缓冲区中写入字符流(send/write)
3.一些进程从消息缓冲区中读出字符流(receive/read)

在这里插入图片描述

6-14 死锁的产生

M 死锁的概念
U 死锁产生的例子
U 死锁解决的三个办法:防止、避免、检测与恢复

死锁:一组进程处于死锁状态是指,每个进程都在等待被另一个进程所占有的、不能抢占的资源。

6-15 死锁的防止

M 死锁产生的必要条件:互斥条件、占有和等待条件、不剥夺条件、循环等待条件
U 死锁的防止方法
M 静态分配方法
M 层次分配方法

死锁的防止:破坏四个必要条件之一
静态分配(顶分配)是常用方法,破坏了第二个条件
层次分配

6-16死锁的避免

U 死锁的避免
M 银行家算法
U 银行家算法的例子

6-17 死锁的检测

你可能感兴趣的:(MOOC南大COS,NOTE)