【问题2】(5分)
若系统中有多个发送进程和接收进程,进程间的工作流程如图4-2所示,其中空(1)~(4)的内容与图4-1相同。发送进程产生消息并顺序地写入环形缓冲区BUFFER,接受者进程顺序地从BUFFER中取消息,且每条消息只能读取一次。为了保证进程间的正常通讯,增加了信号量SA和SB。
① 请说明信号量SA和SB的物理意义,并在图4-2中的空(5)和空(6)处填入正确的内容。
② 请从图4-2的(a)~(1)中选择四个位置正确地插入P(SA)、V(SA)、P(SB)、V(SB)。
【图4-2]】
【问题3】(6分)
设系统中只有进程A和进程B,除了互斥地使用CPU和打印机R外,进程A和B不使用其他资源。另外,进程B的优先级比A高,而进程A先于B准备好。进程A和B的执行情况如图4-3所示,其中粗实线表示进程在执行中,细实线表示打印机R在使用中。(每个进程具有三种状态:运行,就绪和阻塞)
请说明进程A和B在图4-3所示的T1、T2、T3、T4时刻所处的状态;若是阻塞状态,请说明阻塞原因。
【图4-3】
试题五(15分,每空3分)
阅读下列函数说明和C代码,将应填入(n)处的字句写在答题纸的对应栏内。
【说明】
函数int Toplogical (LinkedWDigraph G)的功能是对图G中的顶点进行拓扑排序,并返回关键路径的长度。其中图G表示一个具有n个顶点的AOE-网,图中顶点从1~n依次编号,图G的存储结构采用邻接表表示,其数据类型定义如下:
typedef struct Gnode{ /*邻接表的表结点类型*/
int adjvex; /*邻接顶点编号*/
int weight; /*弧上的权值*/
struct Gonde*nextare; /*指示下一个弧的结点*/
}Gnode;
typedef struct Adjlist{ /*邻接表的头结点类型*/
char vdata; /*顶点的数据信息*/
struct Gnode*Firstadj; /*指向邻接表的第一个表结点*/
}Adjlist;
typedef struct LinkedWDigraph{ /*图的类型*/
int n ,e; /*图中顶点个数和边数*/
struct Adjlist head; /*指向图中第一个顶点的邻接表的头结点*/
}LinkedWDigraph;
例如,某AOE-网如图5-1所示,其邻接表存储结构如图5-2所示。
【函数】
int Toplogical(LinkedWDigraph G)
{Gnode *p;
int j,w,top=0;
int Stack,ve,*indegree;
ve=(int )mallloc(G.n+1)*sizeof(int));
indegree=(int*)malloc((G.n+1)*sizeof(int)); /*存储网中个顶点的入度*/
Stack=(int*)malloc((G.n+1)*sizeof(int)); /*存储入度为0的顶点的编号*/
If (!ve||!indegree||!Stack) exit(0);
for (j=1;j<=G.n;j++){
ve[j]=0;indegree[j]=0;
} /*for*/
for (j=1;j<=G.n;j++) { /*求网中各顶点的入度*/
p=G.head[j].Firstadj;
while (p) {
__(1)__; p=p->nextarc;
} /*while*/
} /*for*/
for (j=1;j<=G.n;j++) /求网中入度为0的顶点并保存其编号*/
if (!indegree[j]) Stack[++top]=j;
while (top>0){
w=__(2)__;
printf(“%c”,G.head[w].vdata);
p=G.head[w].Firstadj;
while (p) {
__(3)__;
if (!indegree[p->adjvex])
Stack[++top]=p->adjvex;
If(__(4)__)
Ve[p->adjvex]=ve[w]+p->weight;
P=p->nextarc;
}/*while*/
return(5);
} /*Toplogical*/
试题六(15分,每空3分)
阅读下列函数说明和C++代码,将应填入(__n__)处的字句写在答题纸的对应栏内。
【说明】
通常情况下,用户可以对应用系统进行配置,并将配置信息保存在配置文件中,应用系统在启动时首先将配置文件加载到内存中,这些内存配置信息应该有且仅有一份。
下面的代码应用了单身模式(Singleton)以保证Configure类只能有一个实例。这样,Configure类的使用者无法定义该类的多个实例,否则会产生编译错误。
【C++代码】
#include <iostream.h>
class Configure {
__(1)__;
Configure() {}; //构造函数
Public;
Static Configure*Instance();
Public;
Int GetConfigureData() {return data;} //获取配置信息
Int SetConfigureDate(int m_data)
{ data=m_data; return data; } //设置配置信息
private:
static Configure*_instance;
int data; //配置信息
};
__(2)__=NULL;
Configure * Configure;;Instance() {
If (_instance= =NULL) {
_instance=__(3)__;
//加载配置文件并设置内存配置信息,此处省略
}
return__(4)__;
}
void main() {
Configure*t=NULL;
t=__(5)__;
int d=t->GetConfigureData();
//获取配置信息后进行其它工作,此处省略
}
试题七(15分,每空3分)
【说明】
类Queue表示队列,类中的方法如下表所示。
isEmpty() |
判断队列是否为空。如果队列不为空,返回true;否则,返回false。 |
Enpueue(object newNode) |
入队操作。 |
Dequeue() |
出队操作。如果队列为空,则抛出异常。 |
类Node表示队列中的元素;类emptyQueueException给出了队列操作中的异常处理操作。
【JAVA代码】
public class testmain { //主类
public static viod main (string args[]){
Queue q= new queue;
q.enqueue(“first!”);
q.enqueue(“second!”);
q.enqueue(“third!”);
__(1)__ {
while(true)
system.out.println(q.dequeue());
}
catch(__(2)__){}
}
public class queue { //队列
node m_firstnode;
public queue(){m_firstnode=null;}
public Boolean isempty(){
if (m_firstnode= =null) return true;
else return false;
}
public viod enqueue(object newnode){ //入队操作
node next = m_firstnode;
if (next = = null) m_firstnode=new node(newnode);
else {
while(next.getnext()!=null) next=next.getnext();
next.setnext(new node(newnode));
}
}
public object dequeue() __(3)__ { //出队操作
object node;
if (is empty())
__(4)__; //队列为空,抛出异常
else {
node =m_firstnode.getobject();
m_firstnode=m_firstnode.getnext();
return node;
}
}
}
public class node{
object m_data;
node m_next;
public node(object data) {m_data=data; m_next=null;}
public node(object data,node next) {m_data=data; m_next=next;}
public void setobject(object data) {m_data=data; }
public object getobject(object data) {return m_data;}
public void setnext(node next) {m_next=next;}
public node getnext() {return m_next;}
}
public class emptyqueueexception extends (5) {
public emptyqueueexception() {
system.out.println(“队列已空!”);
}
}