1.33k likes | 1.47k Views
课程主要内容. 操作系统引论( 1 章) 进程管理( 2-3 章) 存储管理( 4 章) 设备管理( 5 章) 文件管理( 6 章) 操作系统接口( 7 章). 进程管理 --- 第 2 章. 进程的基本概念与控制 2.1 进程的基本概念 2.2 进程控制 2.6 线程的基本概念 2.7 UNIX 中进程的描述与控制. 进程管理 --- 第 2 章. 进程同步与通信 2.3 进程同步 2.4 经典进程的同步问题 2.5 进程通信 调度与死锁(第 3 章). 本章作业. 2.3 进程同步.
E N D
课程主要内容 • 操作系统引论(1章) • 进程管理(2-3章) • 存储管理(4章) • 设备管理(5章) • 文件管理(6章) • 操作系统接口(7章)
进程管理---第2章 • 进程的基本概念与控制 • 2.1 进程的基本概念 • 2.2 进程控制 • 2.6 线程的基本概念 • 2.7 UNIX中进程的描述与控制
进程管理---第2章 • 进程同步与通信 • 2.3 进程同步 • 2.4 经典进程的同步问题 • 2.5 进程通信 • 调度与死锁(第3章) 本章作业
2.3 进程同步 • 进程同步是指对多个相关进程在执行次序上进行协调,它的目的是使系统中诸进程之间能有效地共享资源和相互合作,从而使程序的执行具有可再现性;或系统中诸进程之间在逻辑上的相互制约的关系(直接的-同步;间接的—互斥)。 • 用来实现同步的机制称为同步机制。如:信号量机制;管程机制。
2.3 进程同步 一.进程同步的基本概念 1.两种形式的制约关系 2.临界资源、临界区 3.同步机制应遵循的规则 二.信号量机制 1.整型信号量 2.记录型信号量 3.AND型信号量集、一般信号量集 三.信号量的应用 1.信号量实现进程互斥 2.信号量描述进程间的前趋关系 返回目录
一、进程同步的基本概念 1、两种形式的制约关系 系统中诸进程之间在逻辑上存在着两种制约系: • 直接制约关系;进程之间为了共同完成某项任务,或者协作完成,有意识彼此相互“交换信息”。如前分别将I、C和P都看成是进程。(进程同步) • 间接制约关系;进程之间通过竞争系统某些资源产生的关系称为间接制约关系,它们之间是通过某种“媒介”而产生了“关系”。(进程互斥)
CPU 空闲 CPU 空闲 结束 B打印 A打印 下一步 下一步 下一步 下一步 间接制约关系示例: 打印请求 A完成 用户A 打印请求 B完成 CPU 用户B 打印机 (系统负责打印) A打完 B打完 A进入等待打印完成阻塞队列 B被唤醒从阻塞进入就绪队列,后投入运行 B进入申请打印机阻塞队列 A被唤醒从阻塞进入就绪队列,后投入运行;B分配打印机
一、进程同步的基本概念 同步与互斥的比较
一、进程同步的基本概念 2、临界资源、临界区 临界资源(critical resource) 系统中某些资源一次只允许一个进程使用,称这样的资源为临界资源或互斥资源或共享变量。 临界区(互斥区):critical section 在进程中涉及到临界资源的程序段叫临界区 多个进程的临界区称为相关临界区
… If a < 0 then a := a +1 else a:= a-1 … P1 P3 … a := a +1 print (a) … 互斥 互斥 一、进程同步的基本概念 2、临界资源、临界区 … a := a -1 print (a) … P2 互斥 进程的互斥(间接作用)
一、进程同步的基本概念 2、临界资源、临界区 程序 段1 程序 段3 程序 段2 共享变量
A: R1=X; R1=R1+1; X=R1; B: R2=X; R2=R2+1; X=R2; (1)变量X必需按临界资源处理。 (2)每个进程中访问临界资源的那段代码称为临界区 A: R1=X; B: R2=X; A: R1=R1+1; X=R1; B: R2=R2+1; X=R2; 一、进程同步的基本概念 • 例:有两个进程A和B,它们共享一个变量x,且两个进程按以下方式对变量X进行访问和修改: 其中R1和R2为处理机中的两个 寄存器。A与B均对X+1,即X+2。 若按另一顺序对变量进行修改: 结果x只加了1。
一、进程同步的基本概念 2、临界资源、临界区 实现各进程互斥进入临界区 进程须在临界区前面增加一段用于进行上述检查的代码,称为进入区(entry section)。在临界区后面加上一段称为退出区(exit section)的代码 While (1) { 进入区代码; 临界区代码; 退出区代码; 其余代码 ; }
进入区 临界区 退出区 剩余区 一、进程同步的基本概念 2、临界资源、临界区 • 要进入临界区的若干进程必须满足: (1)一次只允许一个进程进入临界区 (2)任何时候,处于临界区的进程不得多于一个 (3)进入临界区的进程要在有限的时间内退出 (4)如果不能进入自己的临界区,则应让出处理机资源 • 解决临界区(互斥)问题的方法:P-V操作
3、同步机制应遵循的规则 一、进程同步的基本概念 • 有空让进(空闲让进):当无进程处于临界区时,表明临界资源处于空闲状态,应允许一个请求进入临界区的进程立即进入自己的临界区,以有效地利用临界资源。 • 互斥(忙则等待):当已有进程进入临界区时,表明临界资源正在被访问,因而其他试图进入临界区的进程必须等待,以保证对临界资源的互斥访问。
一、进程同步的基本概念 3、同步机制应遵循的规则 • 有限等待:对要求访问临界资源的进程,应保证在有限时间内能进入自己的临界区,以免陷入“死等”状态。 • 让权等待:当进程不能进入自己的临界区时,应立即释放处理机,以免进程陷入“忙等”。 返回
二、信号量机制 • 信号量机制是荷兰科学家E.W.Dijkstra在1965年提出的一种同步机制,也称为P、V操作。由最初的整型信号量发展为记录型信号量,进而发展为信号量集。 • 整型信号量 • 记录型信号量 • 信号量集(AND信号量集、一般信号量集)
1、整型信号量 • 整型信号量——非负整数,除了初始化外,只能通过两个原子操作wait和signal(P,V)来访问。 • wait和signal操作描述: wait(S): while S0 do no-op 测试有无可用资源 S:=S-1; 可用资源数减一个单位signal(S): S:=S+1; • 主要问题:只要S0, wait操作就不断地测试(盲等),因而,未做到“让权等待”。
2、记录型信号量 • 基本思想 1、设置一个代表资源数目的整型变量value(资源信号量) 2、设置一链表L用于链接所有等待的进程 • 记录型信号量的数据结构 Type semaphore=record value:integer; L: list of process; end
2、记录型信号量 • P、V操作 除初始化外,仅能通过两个标准的原子操作wait(S)和signal(S)来访问。很长时间以来,这两个操作一直被称为P、V操作。 原子操作(atomic action)或简称“原语”(primitive):在执行上不可中断的操作。
2、记录型信号量 • P、V操作定义 P(s) /*= wait(s))*/ { s.value=s.value-1; if (s.value < 0) block(s.queue) } 该进程状态置为等待状态 将该进程的PCB插入相的等待队列末尾s.queue;
2、记录型信号量 • P、V操作定义 V(s) /*=signal(s) */ { s.value=s.value+1; if (s.value <= 0) wakeup(s.queue) } 唤醒相应等待队列s.queue中等待的一个进程 改变其状态为就绪态 并将其插入就绪队列
2、记录型信号量 • P、V操作含义 • 信号量的物理含义: • S>0 表示有S个资源可用 • S=0 表示无资源可用 • S<0 则 |S| 表示S等待队列中的进程个数 • P、V操作的含义 • P(S):表示申请一个资源 • V(S):表示释放一个资源。信号量的初值应≥0
3、信号量集---AND型信号量 • AND型信号量的基本思想 将进程在整个运行过程中所需要的所有临界资源,一次性全部分配给进程,待进程使用完后再一起释放。只要有一个资源未能分配给进程,其它所有可能分配的资源也不分配给该进程。从而可避免死锁发生。在wait操作中,增加了一个“AND”条件,故称为AND同步。
3、信号量集---AND型信号量 Swait(S1, S2, …, Sn) //P原语; { while (TRUE) { if (S1 >=1 && S2 >= 1 && … && Sn >= 1) { //满足资源要求时的处理; for (i = 1; i <= n; ++i) -–Si; //注:与P的处理不同,这里是在确信可满足 // 资源要求时,才进行减1操作; } else { //某些资源不够时的处理; 调用进程进入第一个小于1信号量的等待队Sj.queue; 阻塞调用进程; } Ssignal(S1, S2, …, Sn) //V原语略;见书
3、信号量集---一般信号量 • 一般信号量集是指同时需要多种资源、每种占用的数目不同、且可分配的资源还存在一个临界值时的信号量处理 • 一般信号量集的基本思路就是在AND型信号量集的基础上进行扩充,在一次原语操作中完成所有的资源申请。
3、信号量集---一般信号量 • 进程对信号量Si的 测试值为ti(表示信号量的判断条件,要求Si >= ti;即当资源数量低于ti时,便不予分配) 占用值为di(表示资源的申请量,即Si = Si - di) 对应的P、V原语格式为: • Swait(S1, t1, d1; ...; Sn, tn, dn); • Ssignal(S1, d1; ...; Sn, dn);
3、信号量集---一般信号量 一般“信号量集”可以用于各种情况的资源分配和释放,几种特殊情况: • Swait(S, d, d)表示每次申请d个资源,当少于d个时,便不分配 • Swait(S, 1, 1)表示互斥信号量 • Swait(S, 1, 0)可作为一个可控开关(当S1时,允许多个进程进入临界区;当S=0时,禁止任何进程进入临界区) 返回
三、信号量的应用 • 利用信号量实现进程互斥 Process1: Process2: while (true) { P(mutex); critical section; V(mutex); remainder section; } while (true) { P(mutex); critical section; V(mutex); remainder section; }
三、信号量的应用 例:三个进程共用两个I/O缓冲区。 • 解:设用信号量S表示共享资源,S初始值为2
P1 P2 P3 P(mutex) P(mutex) V(mutex) P(mutex) V(mutex) V(mutex) 互斥区 三、信号量的应用
P1 P2 三、信号量的应用 • 利用信号量实现前驱关系 设置一个信号量S,其初值为0, P(S); P2; P1; V(S); 如此即可实现先执行P1,再执行P2
a b d c s1 s3 s2 s4 S1() { … v(a); } S2() { … v(b); v(c); } S3() { p(a); p(b); … v(d); } S4() { p(c); p(d); ... } 三、信号量的应用 Eg: 设S1,S2,S3,S4为一组合作进程,其前趋图如图所示,用P、V操作实现其同步。 • 利用信号量实现前驱关系(同步例子) var a,b,c,d:semaphore:=0,0,0,0; /*表示进程是否执行完*/ main() { cobegin s1(); s2(); s3(); s4(); coend }
三、信号量的应用 • 利用信号量实现前驱关系(同步例子) 思考: 已知一个求值公式(A2/3B)/(B+5A), 若A、B已赋值,画出该公式求值过程的前趋图
三、信号量的应用 • 利用信号量实现同步 • 有A、B两进程,A进程从卡片机读信息入缓冲区,B进程负责加工读进缓冲区的卡片 • 解:设信号量S1:缓冲区中有否可供加工的信息,初始值为0;信号量S2:缓冲区是否为空,初始值为1。
三、信号量的应用 • 利用信号量实现同步举例 返回
2.4 经典进程的同步问题 在多道程序环境下,进程同步问题十分重要,出现一系列经典的进程同步问题,其中有代表性有: • 生产者—消费者问题 • 哲学家进餐问题 • 读者—写者问题 返回目录
生产者 消费者 1、“生产者—消费者”问题 单缓冲区:生产者进程P和消费者进程C共用一个缓冲区,P生产产品放入缓冲区,C从缓冲区取产品来消费。
1、“生产者—消费者”问题 • 单缓冲区的同步问题 • P进程不能往“满”的缓冲区中放产品,设置信号量为empty • C进程不能从“空”的缓冲区中取产品,设置信号量full • 单缓冲区的互斥问题 • P、C进程不能同时使用缓冲区
1、“生产者—消费者”问题 • 单缓冲区的生产者─消费者问题解 P: C: while (true) { while (true) { 生产一个产品; P(full); P(empty) ; 从缓冲区取产品; 送产品到缓冲区; V(empty); V(full); 消费产品; }; }; empty初值为1,full初值为0
生产者 消费者 C P .... n m k k个 Buffer 1、“生产者—消费者”问题 多个缓冲区:若干个生产者进程P1, P2, …, Pn,若干个消费者进程Cl,C2,…,Cm。它们通过一个有界缓冲池(k个)联系。
1、“生产者—消费者”问题 • 多缓冲区的同步互斥问题 • 同步:当缓冲池已放满了产品时(供过于求),生产者进程必须等待;当缓冲池已空时(供不应求),消费者进程应等待。 • 互斥:所有进程应互斥使用缓冲池这一临界资源。
1、“生产者—消费者”问题 • 多缓冲区的生产者─消费者问题解法 设置两个同步信号量及一个互斥信号量 • empty:说明空缓冲单元的数目,其初值为有界缓冲区的 大小n。 • full:说明满缓冲单元的数目(即产品数目),其初值为0。 • mutex:说明该有界缓冲区是一临界资源,必须互斥使用,其初值为1。
1、“生产者—消费者”问题 • 多缓冲区的生产者─消费者问题解法 思考:P操作的顺序可换吗?
1、“生产者—消费者”问题 • “生产者—消费者”问题的算法描述 semaphore full=0; /*表示满缓冲区的数目*/ semaphore empty=n; /*表示空缓冲区的数目*/ semaphore mutex=1; /*表示对缓冲区进程操作的互斥信号量*/ Main() { cobegin producer(); consumer(); coend }
Consumer() Producer() { while(true) { p(full); P(mutex); 从缓冲区取走一个产品; V(mutex); V(empty); 消费一个产品; } } { while(true) { 生产一个产品; P(empty); P(mutex); 将一个产品送入缓冲区; V(mutex); V(full); } } 1、“生产者—消费者”问题 • “生产者—消费者”问题的算法描述
“生产者-消费者”问题中应注意 1、“生产者—消费者”问题 1.互斥信号量的P,V操作在每一程序中必须成对出现. 2.资源信号量(full,empty)也必须成对出现,但可分别处于不同的程序中. 3.多个P操作顺序不能颠倒. 4.先执行资源信号量的P操作,再执行互斥信号量的P操作,否则可能引起进程死锁.
1、“生产者—消费者”问题 • “生产者-消费者”问题中应注意 5.它是一个同步问题: (1)消费者想要取产品,有界缓冲区中至少有一个单元是满的。 (2)生产者想要放产品,有界缓冲区中至少有一个是空的。 6.它是一互斥问题 有界缓冲区是临界资源,因此,各生产者进程和各消费者进程必须互斥执行。 返回
2、“哲学家进餐”问题 • 问题描述 • 5个哲学家围坐在圆桌旁,每人面前有一只空盘子,每2人之间放一只筷子,如图所示。 • 为了就餐,每个哲学家必须拿到两只筷子,并且只能直接从自己的左边或右边去取筷子。
哲学家进餐问题的解决 2、“哲学家进餐”问题 semaphore stick[5]={1,1,1,1,1}; /*分别表示5支筷子*/ Main() { cobegin philosopher(0); philosopher(1); philosopher(2); philosopher(3); philosopher(4); coend }