Cao Zuo Xi Tong
1.模式切换与进程切换
进程切换指让处于运行态的进程中断运行,要让出处理器,这时要做一次进程上下文的切换,就是保存老进程状态而装入被保护了的新进程的状态,以便新程序运行。
CPU模式切换指当中断或者系统调用发生时,暂时中断正在执行的用户进程,把进程从用户状态切换成内核状态,去执行系统服务程序以获得服务。
2.内部碎片和外部碎片
碎片是指在内存中无法被利用的小空闲区。内部碎片是指分配给作业的存储空间中未被利用的部分;外部碎片是指在系统中无法利用的小存储块。如固定分区分配中存在内部碎片,动态分区分配中存在外部碎片。
3.设备独立性
用户不指定特定设备,指定逻辑设备,使得用户作业和物理设备独立开来,通过其它途径建立逻辑设备和物理设备之间的对应关系,这种特性叫设备独立性。设备独立性的好处在于,用户和物理的外围设备无关,系统增减或变更物理外围设备时不用修改程序;易于对付输入输出设备的故障。
4.死锁的定义以及死锁产生的必要条件
如果在一个进程集合中每个进程都在等待只能由该集合中的其他一个进程才能引发的事件,则称一组进程或者系统发生死锁。
系统形成死锁的必要条件:
互斥条件:进程要求对所分配的资源进行排它性控制;
部分分配条件:进程在等待申请的新资源的同时,不释放已占有资源;
不剥夺条件:一个进程不能抢劫其它进程占有的资源,只能被动等待该资源的释放;
环路等待条件:存在一种进程资源的循环等待链,链中每一个进程所获得的资源同时被链中下一个进程所请求。
5.I/O控制方式中,DMA方式和通道方式的比较
DMA方式的基本思想:外设在硬件支持下直接与内存交换成批数据,数据传送过程无需CPU干预;不过在DMA方式中,数据传送的方向,存放数据的内存始址及传送数据的长度等仍然由CPU控制。
通道方式:通道是一个专管输入/输出工作的处理机,具有自己的指令系统,它的指令常称通道命令。在通道控制方式下,CPU在遇到I/O请求时,启动指定通道上选址的外围设备,一旦启动成功,通道就能完成相应的I/O操作,并在I/O操作结束时向CPU发送中断信号。由此可见,CPU仅在I/O操作开始和结束时花极短的时间处理与I/O操作有关的事宜,其余时间都在与通道并行工作;此外一个通道还能控制多台外围设备,可以完成复杂的I/O控制。
6.外中断和内中断
外中断是指来自处理器和内存外部的中断,包括I/O设备发出的中断,时钟中断,操作员控制台中断等。
内中断主要指在处理机和内存内部产生的中断,也称为异常,它包括程序运算引起的错误。
7.进程调度与作业调度
作业调度按一定的算法从磁盘上的“输入井”中选择资源能得到满足的作业装入内存,使作业有机会去占用处理器执行。
但是,一个作业能否占用处理器,什么时间能够占用处理器,必须由进程调度来决定。所以,作业调度选中了一个作业且把它装入内存时,就应为该作业创建一个进程,若有多个作业被装入内存,则内存中同时存在多个进程,这些进程的初始状态为就绪状态,然后,由进程调度来选择当前可占用处理器的进程,进程运行中由于某种原因状态发生变化,当它让出处理器时,进程调度就再选另一个作业的进程运行。
第一题:(参考第六章第17题)
在一个操作系统中,inode节点中分别含有10 个直接地址的索引和一、二、三级间接索引。若设每个盘块有512B 大小,每个盘块中可存放128个盘块地址,则(1)一个1MB的文件占用多少间接盘块?(2)一个20MB 的文件占用多少间接盘块?
解:
直接块容量=10×512/1024=5KB
一次间接容量=128×512/1024=64KB
二次间接容量=128×128×512/1024=64KB×128=8192KB
三次间接容量=128×128×128×512/1024=64KB×128=8192KB×128=1048576KB
1MB 为1024KB,1024KB-69KB=955KB,955×1024B/512B=1910块,1MB的文件分别占用1910个二次间接盘块。
20×1024KB-69-8192=12219KB,12219×1024/512=24438块,20MB的文件分别占用24438个三次间接盘块和8192个二次间接盘块。
第二题:(数据参考第5章第7题)
最短查找时间优先算法SSTF;扫描算法SCAN;循环扫描算法C-SCAN;磁道0-199;当前存取臂在143,请求队列的先后顺序是:86,147,91,177,94,150,102,175,130;求三种算法的访问队列;按照所用时间从少到多把三种算法进行排列。
解:
SSTF依次为
143-147-150-130-102-94-91-86-175-177。
SCAN依次为(来回扫描,碰到0或199时转变方向)
143-147-150-175-177-199-130-102-94-91-86。
C-SCAN次为(总是从0到199的方向扫描,到尽头直接又回到0开始扫描)
143-147-150-175-177-199-0-86-91-94-102-130。
按照所用时间从少到多进行排列为
SSTF,SCAN,C-SCAN
第三题:(参考第二章28题)(注意进程调度与作业调度的区别,资源的满足与否)
某多道程序设计系统采用可变分区主存管理,供用户使用的主存为200K,磁带机5台。采用静态方式分配外围设备,且不能移动在主存中的作业,进程调度采用FCFS,忽略用户作业I/O 时间。现有作业序列如下:
作业号 进入输入井时间 运行时间 主存需求量 磁带需求
A 8:30 40分钟 30K 3
B 8:50 25分钟 120K 1
C 9:00 35分钟 100K 2
D 9:05 20分钟 20K 3
E 9:10 10分钟 60K 1
SJF短作业优先算法选中作业执行的次序及作业平均周转时间。
解:
作业执行的次序为:A、B、D、E C
作业平均周转时间 (40+45+50+90+90)/5=63 分钟
(1) 8:30 作业A 到达并投入运行
(2) 8:50 作业B 到达,资源满足进主存就绪队列等CPU。
(3) 9:00 作业C 到达,主存和磁带机均不够,进后备作业队列等待。
(4) 9:05 作业D 到达,磁带机不够,进后备作业队列等待。后备作业队列有C、D。
(5) 9:10 作业A 运行结束,归还资源磁带,但注意主存不能移动(即不能紧缩)。作业B
投入运行。作业C 仍因主存不够而等在后备队列。这时作业E 也到达了,虽然该作业最短,
也由于主存不够进入后备作业队列。此时作业D 因资源满足(主存/磁带均满足),进主存就
绪队列等待。后备作业队列还有C、E。
(6)9:35 作业B 运行结束,作业D 投入运行。这时作业C 和E 资源均满足,但按SJF
应把作业E 调入主存进就绪队列等CPU。而作业C 因磁带机不够继续在后备作业队列等待。
(7)9:55 作业D 运行结束,作业C 调入主存进就绪队列等CPU。
(8)10:05 作业E 运行结束,作业C 投入运行。
(9)10:40 作业C 运行结束。
第四题:(CPU利用率=CPU有效工作时间/CPU总的运行时间)
三个程序A,B,C单独运行所需时间30min,40min,60min,各自在CPU中运行的时间为15min,20min,30min;现使用多道分时系统,此时CPU利用率80%,增加系统额外开销时间18.75min,请问程序可并发执行之后系统效率提高多少?
解:
原来CPU工作的总时间 15+20+30=65
原来的总时间 30+40+60=130
原来的系统效率 65/130=50%
现在CPU工作的总时间 65/80%=81.25
现在的总时间 30+20+15+15+18.75=98.75
现在的系统效率 81.25/98.75
第五题:
1)页长256?分页,框,逻辑地址,替换队列
2)LRU和第二次机会算法,比较缺页率。(部分参考第四章47题)
第六题:(资源分配,安全序列,安全状态,银行家算法)
1)Request<=Need(Need=Claim-Available)
2)Request<=Available
3)Available=Available-Request;
Allocation=Allocation+Request;
Need=Need-Request;
4)执行安全算法检查
(a)设置两个向量
Work=Available;
Finish(i)==false;
(b)寻找一个满足下述条件的进程,找到则执行步骤(c),否则执行步骤(d)
Finish(i)==false;
Need<=Work;
(c)进程Pi执行完后释放资源,然后执行步骤(b)
Work=Work+Allocation;
Finish(i)==true;
(d)若所有的进程Finish都为true,则系统处于安全状态;否则,系统处于不安全状态。
(参考第三章29题,或者课件ch3-3.6死锁)
系统有A、B、C、D 共4 种资源,在某时刻进程P0、P1、P2、P3 和P4 对资源的占有
和需求情况如表,试解答下列问题:
Allocation Claim Available
Process A B C D A B C D A B C D
P0 0 0 3 2 0 0 4 4 1 6 2 2
P1 1 0 0 0 2 7 5 0
P2 1 3 5 4 3 6 10 10
P3 0 3 3 2 0 9 8 4
P4 0 0 1 4 0 6 6 10
1)系统此时处于安全状态吗?
2)若此时P2 发出request2(1、2、2、2),系统能分配资源给它吗?为什么?
解:(1)系统处于安全状态,存在安全序列:P0,P3,P4,P1,P2。
(2)不能分配,否则系统会处于不安全状态。
第七题:河两岸左右两队人过独木桥,桥上每次过一人,必需同一队人先走完,才能轮到另一队
解:
设信号量: MUTEX=1 (东西方互斥)
MZ=1 (左向右使用计数变量互斥)
MY=1 (右向左使用计数变量互斥)
int CZ=0 (左向右的已上桥人数)
int CY=0 (右向左的已上桥人数)
process Left(){
P (MZ);
IF (CZ=0)
{P (MUTEX); }
CZ=CZ+1;
V (MZ);
过桥;
P (MZ);
CZ=CZ-1;
IF (CZ=0)
{V (MUTEX); }
V (MZ);
}
process Right(){
P (MY);
IF (CY=0)
{P (MUTEX) ; }
CY=CY+1;
V (MY);
过桥;
P (MY);
CY=CY-1;
IF (CY=0)
{V (MUTEX) ; }
V (MY);
}
第八题:(参考第三章第45题)
(往年的题目曾经是第三章27题:今有k 个进程,它们的标号依次为1、2、…、k,如果允许它们同时读文件file,但必须满足条件:参加同时读文件的进程的标号之和需小于M(k<M),请使用:1)信号量与P、V 操作,2)管程,编写出协调多进程读文件的程序。)
桌上有一只盘子,最多可以容纳两个水果,每次仅能放入或取出一个水果。爸爸向盘子
中放苹果(apple),妈妈向盘子中放桔子(orange),两个儿子专等吃盘子中的桔子,两个女儿
专等吃盘子中的苹果。试用管程,来实现爸爸、妈妈、儿子、女儿间的同步与互斥关系。
管程实现:
TYPE FMSD = MONITOR
enum {apple, orange} plate[2];
int count; bool flag0,flag1;
semaphore SP, SS, SD ;
int SP_count,SS_count,SD_count;
count=0;flag0=false;flag1=false;
plate[0]=plate[1]=null;
InterfaceModule IM;
DEFINE put, get;
USE wait, signal, enter, leave;
void put(FRUIT fruit) {
enter(IM);
if(count==2) wait(SP,SP_count,IM);
else {if(flag0==false)
{plate[0]=fruit;flag0=true;}
else {plate[1]=fruit; flag1=true; }
count++;
if(fruit==orange) signal(SS,SS_count,IM);
else signal(SD,SD_count,IM);
}
leave(IM);
}
void get(FRUIT fruit, FRUIT &x) {
enter(IM);
if ((count==0)‖plate!=fruit)
if (fruit==orange) wait(SS,SS_count,IM);
else wait(SD,SD_count,IM);
count--;
if (flag0&&plate[0]= =fruit)
{x=plate[0];flag0=false;}
else {x=plate[1]; flag1=false;}
signal(SP, SP_count,IM);
leave(IM);
}
cobegin
process father( ) {
while (true) {
{准备好苹果};
FMSD.put(apple);
}
}
process mother( ) {
while (true) {
{准备好桔子};
FMSD.put(orange);
}
}
process son( ) {
while (true) {
FMSD.get(orange,x);
{吃取到的桔子};
}
}
process daughter( ) {
while (true) {
FMSD.get(apple,x);
{吃取到的苹果};
}
}
Coend
信号量和P、V 操作
a.同步信号量初值为2
b.引进一个互斥信号量mutex,用于“访问”盘子的互斥
c.盘子中每一项用橘子,苹果这两个枚举值
enum{apple,orange}plate[2];
semaphore mutex; /*互斥:每次仅能放入或取出一个水果*/
semaphore amount; /*同步:盘子可以容纳两个水果*/
semaphore ppp,jjj; /*有或要苹果,有或要橘子*/
boolean flag1,flag2; /*装了一个水果,装了两个水果*/
mutex=1;
amount=2;
ppp=jjj=0;
flag1=flag2=false;
cobegin
processFather(){
while(true){
削一个苹果;
P(amount); /*这里的P操作的意思是我在等着可以往盘子里放水果?*/
P(mutex);
if(flag1==false){
plate[0]=苹果;
flag1==true;
}
else{
plate[1]=苹果;
flag2==true;
}
V(mutex);
V(ppp);
}
}
processMother(){
while(true){
剥一个橘子;
P(amount);
P(mutex);
if(flag1==false){
plate[0]=橘子;
flag1==true;
}
else{
plate[1]=橘子;
flag2==true;
}
V(mutex);
V(jjj);
}
}
processDaughter(){
while(true){
P(ppp);
P(mutex);
if(flag1&&plate[0]==苹果){
取苹果; /*参考代码是x=plate[0],意义不明的x从哪来?*/
flag1==false;
}
else{
取苹果; /*参考代码是x=plate[1],大概又是取走苹果么?为什么不考虑盘子为空的状况?大概因为盘子除了初始状态为空之外,后来都不可能再为空,所以根本不予考虑?*/
flag2==false;
}
V(mutex);
V(amount); /*这里V操作的目的难道是:盘子里的水果少了一个,可以派人往里面放水果了*/
吃苹果;
}
}
processSon(){
while(true) {
P(jjj);
P(mutex);
if (flag1&&plate[0]= =桔子)
{ x = plate[0];flag1=false;}
else { x= plate[1]; flag2=false;}
V(mutex);
V(amount);
吃桔子;
}
}
coend
进程切换指让处于运行态的进程中断运行,要让出处理器,这时要做一次进程上下文的切换,就是保存老进程状态而装入被保护了的新进程的状态,以便新程序运行。
CPU模式切换指当中断或者系统调用发生时,暂时中断正在执行的用户进程,把进程从用户状态切换成内核状态,去执行系统服务程序以获得服务。
2.内部碎片和外部碎片
碎片是指在内存中无法被利用的小空闲区。内部碎片是指分配给作业的存储空间中未被利用的部分;外部碎片是指在系统中无法利用的小存储块。如固定分区分配中存在内部碎片,动态分区分配中存在外部碎片。
3.设备独立性
用户不指定特定设备,指定逻辑设备,使得用户作业和物理设备独立开来,通过其它途径建立逻辑设备和物理设备之间的对应关系,这种特性叫设备独立性。设备独立性的好处在于,用户和物理的外围设备无关,系统增减或变更物理外围设备时不用修改程序;易于对付输入输出设备的故障。
4.死锁的定义以及死锁产生的必要条件
如果在一个进程集合中每个进程都在等待只能由该集合中的其他一个进程才能引发的事件,则称一组进程或者系统发生死锁。
系统形成死锁的必要条件:
互斥条件:进程要求对所分配的资源进行排它性控制;
部分分配条件:进程在等待申请的新资源的同时,不释放已占有资源;
不剥夺条件:一个进程不能抢劫其它进程占有的资源,只能被动等待该资源的释放;
环路等待条件:存在一种进程资源的循环等待链,链中每一个进程所获得的资源同时被链中下一个进程所请求。
5.I/O控制方式中,DMA方式和通道方式的比较
DMA方式的基本思想:外设在硬件支持下直接与内存交换成批数据,数据传送过程无需CPU干预;不过在DMA方式中,数据传送的方向,存放数据的内存始址及传送数据的长度等仍然由CPU控制。
通道方式:通道是一个专管输入/输出工作的处理机,具有自己的指令系统,它的指令常称通道命令。在通道控制方式下,CPU在遇到I/O请求时,启动指定通道上选址的外围设备,一旦启动成功,通道就能完成相应的I/O操作,并在I/O操作结束时向CPU发送中断信号。由此可见,CPU仅在I/O操作开始和结束时花极短的时间处理与I/O操作有关的事宜,其余时间都在与通道并行工作;此外一个通道还能控制多台外围设备,可以完成复杂的I/O控制。
6.外中断和内中断
外中断是指来自处理器和内存外部的中断,包括I/O设备发出的中断,时钟中断,操作员控制台中断等。
内中断主要指在处理机和内存内部产生的中断,也称为异常,它包括程序运算引起的错误。
7.进程调度与作业调度
作业调度按一定的算法从磁盘上的“输入井”中选择资源能得到满足的作业装入内存,使作业有机会去占用处理器执行。
但是,一个作业能否占用处理器,什么时间能够占用处理器,必须由进程调度来决定。所以,作业调度选中了一个作业且把它装入内存时,就应为该作业创建一个进程,若有多个作业被装入内存,则内存中同时存在多个进程,这些进程的初始状态为就绪状态,然后,由进程调度来选择当前可占用处理器的进程,进程运行中由于某种原因状态发生变化,当它让出处理器时,进程调度就再选另一个作业的进程运行。
第一题:(参考第六章第17题)
在一个操作系统中,inode节点中分别含有10 个直接地址的索引和一、二、三级间接索引。若设每个盘块有512B 大小,每个盘块中可存放128个盘块地址,则(1)一个1MB的文件占用多少间接盘块?(2)一个20MB 的文件占用多少间接盘块?
解:
直接块容量=10×512/1024=5KB
一次间接容量=128×512/1024=64KB
二次间接容量=128×128×512/1024=64KB×128=8192KB
三次间接容量=128×128×128×512/1024=64KB×128=8192KB×128=1048576KB
1MB 为1024KB,1024KB-69KB=955KB,955×1024B/512B=1910块,1MB的文件分别占用1910个二次间接盘块。
20×1024KB-69-8192=12219KB,12219×1024/512=24438块,20MB的文件分别占用24438个三次间接盘块和8192个二次间接盘块。
第二题:(数据参考第5章第7题)
最短查找时间优先算法SSTF;扫描算法SCAN;循环扫描算法C-SCAN;磁道0-199;当前存取臂在143,请求队列的先后顺序是:86,147,91,177,94,150,102,175,130;求三种算法的访问队列;按照所用时间从少到多把三种算法进行排列。
解:
SSTF依次为
143-147-150-130-102-94-91-86-175-177。
SCAN依次为(来回扫描,碰到0或199时转变方向)
143-147-150-175-177-199-130-102-94-91-86。
C-SCAN次为(总是从0到199的方向扫描,到尽头直接又回到0开始扫描)
143-147-150-175-177-199-0-86-91-94-102-130。
按照所用时间从少到多进行排列为
SSTF,SCAN,C-SCAN
第三题:(参考第二章28题)(注意进程调度与作业调度的区别,资源的满足与否)
某多道程序设计系统采用可变分区主存管理,供用户使用的主存为200K,磁带机5台。采用静态方式分配外围设备,且不能移动在主存中的作业,进程调度采用FCFS,忽略用户作业I/O 时间。现有作业序列如下:
作业号 进入输入井时间 运行时间 主存需求量 磁带需求
A 8:30 40分钟 30K 3
B 8:50 25分钟 120K 1
C 9:00 35分钟 100K 2
D 9:05 20分钟 20K 3
E 9:10 10分钟 60K 1
SJF短作业优先算法选中作业执行的次序及作业平均周转时间。
解:
作业执行的次序为:A、B、D、E C
作业平均周转时间 (40+45+50+90+90)/5=63 分钟
(1) 8:30 作业A 到达并投入运行
(2) 8:50 作业B 到达,资源满足进主存就绪队列等CPU。
(3) 9:00 作业C 到达,主存和磁带机均不够,进后备作业队列等待。
(4) 9:05 作业D 到达,磁带机不够,进后备作业队列等待。后备作业队列有C、D。
(5) 9:10 作业A 运行结束,归还资源磁带,但注意主存不能移动(即不能紧缩)。作业B
投入运行。作业C 仍因主存不够而等在后备队列。这时作业E 也到达了,虽然该作业最短,
也由于主存不够进入后备作业队列。此时作业D 因资源满足(主存/磁带均满足),进主存就
绪队列等待。后备作业队列还有C、E。
(6)9:35 作业B 运行结束,作业D 投入运行。这时作业C 和E 资源均满足,但按SJF
应把作业E 调入主存进就绪队列等CPU。而作业C 因磁带机不够继续在后备作业队列等待。
(7)9:55 作业D 运行结束,作业C 调入主存进就绪队列等CPU。
(8)10:05 作业E 运行结束,作业C 投入运行。
(9)10:40 作业C 运行结束。
第四题:(CPU利用率=CPU有效工作时间/CPU总的运行时间)
三个程序A,B,C单独运行所需时间30min,40min,60min,各自在CPU中运行的时间为15min,20min,30min;现使用多道分时系统,此时CPU利用率80%,增加系统额外开销时间18.75min,请问程序可并发执行之后系统效率提高多少?
解:
原来CPU工作的总时间 15+20+30=65
原来的总时间 30+40+60=130
原来的系统效率 65/130=50%
现在CPU工作的总时间 65/80%=81.25
现在的总时间 30+20+15+15+18.75=98.75
现在的系统效率 81.25/98.75
第五题:
1)页长256?分页,框,逻辑地址,替换队列
2)LRU和第二次机会算法,比较缺页率。(部分参考第四章47题)
第六题:(资源分配,安全序列,安全状态,银行家算法)
1)Request<=Need(Need=Claim-Available)
2)Request<=Available
3)Available=Available-Request;
Allocation=Allocation+Request;
Need=Need-Request;
4)执行安全算法检查
(a)设置两个向量
Work=Available;
Finish(i)==false;
(b)寻找一个满足下述条件的进程,找到则执行步骤(c),否则执行步骤(d)
Finish(i)==false;
Need<=Work;
(c)进程Pi执行完后释放资源,然后执行步骤(b)
Work=Work+Allocation;
Finish(i)==true;
(d)若所有的进程Finish都为true,则系统处于安全状态;否则,系统处于不安全状态。
(参考第三章29题,或者课件ch3-3.6死锁)
系统有A、B、C、D 共4 种资源,在某时刻进程P0、P1、P2、P3 和P4 对资源的占有
和需求情况如表,试解答下列问题:
Allocation Claim Available
Process A B C D A B C D A B C D
P0 0 0 3 2 0 0 4 4 1 6 2 2
P1 1 0 0 0 2 7 5 0
P2 1 3 5 4 3 6 10 10
P3 0 3 3 2 0 9 8 4
P4 0 0 1 4 0 6 6 10
1)系统此时处于安全状态吗?
2)若此时P2 发出request2(1、2、2、2),系统能分配资源给它吗?为什么?
解:(1)系统处于安全状态,存在安全序列:P0,P3,P4,P1,P2。
(2)不能分配,否则系统会处于不安全状态。
第七题:河两岸左右两队人过独木桥,桥上每次过一人,必需同一队人先走完,才能轮到另一队
解:
设信号量: MUTEX=1 (东西方互斥)
MZ=1 (左向右使用计数变量互斥)
MY=1 (右向左使用计数变量互斥)
int CZ=0 (左向右的已上桥人数)
int CY=0 (右向左的已上桥人数)
process Left(){
P (MZ);
IF (CZ=0)
{P (MUTEX); }
CZ=CZ+1;
V (MZ);
过桥;
P (MZ);
CZ=CZ-1;
IF (CZ=0)
{V (MUTEX); }
V (MZ);
}
process Right(){
P (MY);
IF (CY=0)
{P (MUTEX) ; }
CY=CY+1;
V (MY);
过桥;
P (MY);
CY=CY-1;
IF (CY=0)
{V (MUTEX) ; }
V (MY);
}
第八题:(参考第三章第45题)
(往年的题目曾经是第三章27题:今有k 个进程,它们的标号依次为1、2、…、k,如果允许它们同时读文件file,但必须满足条件:参加同时读文件的进程的标号之和需小于M(k<M),请使用:1)信号量与P、V 操作,2)管程,编写出协调多进程读文件的程序。)
桌上有一只盘子,最多可以容纳两个水果,每次仅能放入或取出一个水果。爸爸向盘子
中放苹果(apple),妈妈向盘子中放桔子(orange),两个儿子专等吃盘子中的桔子,两个女儿
专等吃盘子中的苹果。试用管程,来实现爸爸、妈妈、儿子、女儿间的同步与互斥关系。
管程实现:
TYPE FMSD = MONITOR
enum {apple, orange} plate[2];
int count; bool flag0,flag1;
semaphore SP, SS, SD ;
int SP_count,SS_count,SD_count;
count=0;flag0=false;flag1=false;
plate[0]=plate[1]=null;
InterfaceModule IM;
DEFINE put, get;
USE wait, signal, enter, leave;
void put(FRUIT fruit) {
enter(IM);
if(count==2) wait(SP,SP_count,IM);
else {if(flag0==false)
{plate[0]=fruit;flag0=true;}
else {plate[1]=fruit; flag1=true; }
count++;
if(fruit==orange) signal(SS,SS_count,IM);
else signal(SD,SD_count,IM);
}
leave(IM);
}
void get(FRUIT fruit, FRUIT &x) {
enter(IM);
if ((count==0)‖plate!=fruit)
if (fruit==orange) wait(SS,SS_count,IM);
else wait(SD,SD_count,IM);
count--;
if (flag0&&plate[0]= =fruit)
{x=plate[0];flag0=false;}
else {x=plate[1]; flag1=false;}
signal(SP, SP_count,IM);
leave(IM);
}
cobegin
process father( ) {
while (true) {
{准备好苹果};
FMSD.put(apple);
}
}
process mother( ) {
while (true) {
{准备好桔子};
FMSD.put(orange);
}
}
process son( ) {
while (true) {
FMSD.get(orange,x);
{吃取到的桔子};
}
}
process daughter( ) {
while (true) {
FMSD.get(apple,x);
{吃取到的苹果};
}
}
Coend
信号量和P、V 操作
a.同步信号量初值为2
b.引进一个互斥信号量mutex,用于“访问”盘子的互斥
c.盘子中每一项用橘子,苹果这两个枚举值
enum{apple,orange}plate[2];
semaphore mutex; /*互斥:每次仅能放入或取出一个水果*/
semaphore amount; /*同步:盘子可以容纳两个水果*/
semaphore ppp,jjj; /*有或要苹果,有或要橘子*/
boolean flag1,flag2; /*装了一个水果,装了两个水果*/
mutex=1;
amount=2;
ppp=jjj=0;
flag1=flag2=false;
cobegin
processFather(){
while(true){
削一个苹果;
P(amount); /*这里的P操作的意思是我在等着可以往盘子里放水果?*/
P(mutex);
if(flag1==false){
plate[0]=苹果;
flag1==true;
}
else{
plate[1]=苹果;
flag2==true;
}
V(mutex);
V(ppp);
}
}
processMother(){
while(true){
剥一个橘子;
P(amount);
P(mutex);
if(flag1==false){
plate[0]=橘子;
flag1==true;
}
else{
plate[1]=橘子;
flag2==true;
}
V(mutex);
V(jjj);
}
}
processDaughter(){
while(true){
P(ppp);
P(mutex);
if(flag1&&plate[0]==苹果){
取苹果; /*参考代码是x=plate[0],意义不明的x从哪来?*/
flag1==false;
}
else{
取苹果; /*参考代码是x=plate[1],大概又是取走苹果么?为什么不考虑盘子为空的状况?大概因为盘子除了初始状态为空之外,后来都不可能再为空,所以根本不予考虑?*/
flag2==false;
}
V(mutex);
V(amount); /*这里V操作的目的难道是:盘子里的水果少了一个,可以派人往里面放水果了*/
吃苹果;
}
}
processSon(){
while(true) {
P(jjj);
P(mutex);
if (flag1&&plate[0]= =桔子)
{ x = plate[0];flag1=false;}
else { x= plate[1]; flag2=false;}
V(mutex);
V(amount);
吃桔子;
}
}
coend