//根据冒泡法来优先级排序
PCBtemp=arraylist.get(i);
arraylist.set(i,arraylist.get(j));
arraylist.set(j,temp);
}
}
}
}
2.自动从后备队列中往就绪队列中增加进程
//若内存中进程少于规定道数,可从后备队列中调度作业进入
publicvoidcheckPCB(ArrayListready,ArrayListpool){
while(ready.size()<4&&pool.size()>0){
ready.add(pool.get(0));
System.out.println("从后备队列往就绪队列中加入进程");
pool.get(0).getAll();
pool.remove(0);
}
}
3.内存不够时,移入外存队列
publicvoidmove(PCBPCB,ArrayListexternStore,ArrayListPCBready){
if(PCB.isGetStore()==false){
externStore.add(PCB);
PCBready.remove(PCB);
}
}
五、实验总结
1.通过此次实验,对于操作系统的模拟有了更深的理解。
进程的调度,在开始做第一个实验时,由于设计上的漏洞,导致临界资源一直被占用,结果造成了死锁。
在实践中,更加理解了死锁的涵义。
同时,也提醒着自己要不断的总结,注意数据结构方面的设计问题。
2.对于实验内容的理解,我在这方面产生了点困难。
刚开始,不知道如何来模拟临界资源。
在请教了老师之后,慢慢开始摸索。
3.,接触到第二个实验,对于主存空间的模拟又产生了困难。
不知道该用什么来模拟。
最终采用了投机取巧的方式。
用了ArrayList.这样,就不用担心主存的回收问题了。
但是这样,不太符合实际情况。
六、源代码
packageos_check_1;
importjava.util.ArrayList;
importjava.util.Scanner;
publicclassCPU{
staticbooleansource=false;
staticArrayListPCBready=newArrayList();//这里才是真正的就绪队列
staticArrayListpoolQueue=newArrayList();//后备队列
staticArrayListblockQueue=newArrayList();//阻塞队列
staticArrayListendQueue=newArrayList();//结束队列
staticArrayListexternStore=newArrayList();//放入外存的队列
PCBinitpi=newPCBinit();
Scannersc=newScanner(System.in);
MainStorems=newMainStore();
CPU(){
this.PCBready=pi.PCBready;
this.poolQueue=pi.poolQueue;
while(time()>0){
fun();
}
}
//模拟进程的调度
publicvoidfun(){
CPUuse(PCBready);
CheckEnd(PCBready);
CheckBlock();
OutPut();
ms.show();
pi.checkPCB(PCBready,poolQueue);
pi.sort(PCBready);//对可能发生的就绪队列进行优先级排序
System.out.println("***********longxiao************");
}
//剩余运行的时间
publicinttime(){
inttime=0;
for(inti=0;itime=time+PCBready.get(i).getTime();
}
returntime;
}
//从就绪队列中调入优先级最高的运行。
publicvoidCPUuse(ArrayListready){
if(ready.size()>0){
ready.get(0).setState
(1);//将状态设置为运行状态
ms.GetEmpty(ready.get(0));
if(ready.get(0).isGetStore()==true){
if(ready.get(0).getSource()==true){//当需要使用临界资源时
if(source==false||ready.get(0).getUseSource()==true){//临界资源没有被使用
run1(ready);
System.out.println("进程"+ready.get(0).getPID()+"执行");
}else{
blockQueue.add(ready.get(0));//将其加入阻塞队列
ready.remove(0);//将其从就绪队列中移除
}
}else{//不需要使用临界资源的进程
run2(ready);//开始执行
System.out.println("进程"+ready.get(0).getPID()+"执行");
}
}
else{//移入外存
ms.move(ready.get(0),externStore,PCBready);
}
}
}
//设置时间片为3,开始运行。
如果在运行过程中,时间一直不为0.则会占用临界资源
publicvoidrun1(ArrayListready){
for(intx=0;x<=2;x++){//设置时间片为3
ready.get(0).run();//开始执行
if(ready.get(0).getTime()==0){
break;
}else{
source=true;//从此,临界资源被使用
ready.get(0).setUseSource(true);
}
}
if(ready.get(0).getUseSource()==true){
System.out.println("临界资源被"+ready.get(0).getPID()+"占用");
}
}
//不需要临界资源的进程的运行
publicvoidrun2(ArrayListready){
for(intx=0;x<=2;x++){//设置时间片为3
ready.get(0).run();//开始执行
if(ready.get(0).getTime()==0){
break;
}
}
}
//是否应进入结束队列,从就绪队列中移除
publicvoidCheckEnd(ArrayListready){
for(inti=0;iif(ready.get(i).getTime()==0){
ms.release(ready.get(i));//释放所正在使用的内存
ms.check(externStore,PCBready);
System.out.println("test:
checkEnd");
endQueue.add(ready.get(i));
if(ready.get(i).getUseSource()==true){//如果正在使用临界资源
System.out.println("进程"+ready.get(i).getPID()+"释放临界资源");
source=false;//释放临界资源
}
ready.remove(i);
}
}
}
//判断阻塞队列中是否能够进入就绪队列
//前提是占用临界资源的那个进程已经结束
publicvoidCheckBlock(){
pi.sort(blockQueue);//对阻塞队列中的进程进行优先级排序
if(source==false&&blockQueue.size()>0){
System.out.println("test:
checkblock");
//当临界资源出现空闲时,可以从阻塞队列中移除,进入就绪队列。
PCBready.add(blockQueue.get(0));
blockQueue.remove(0);
}
}
publicvoidOutPut(){
System.out.println("就绪队列中有:
"+PCBready.size());
for(inti=0;iPCBready.get(i).getAll();
}
System.out.println("阻塞队列中有:
"+blockQueue.size());
for(inti=0;iblockQueue.get(i).getAll();
}
System.out.println("完成队列中有:
"+endQueue.size());
for(inti=0;iendQueue.get(i).getAll();
}
if(blockQueue.size()!
=0){
System.out.println("是否需要从阻塞队列中唤醒进程(1.YES/ELSE.NO)");
intchoose=sc.nextInt();
if(choose==1){
wakeUp();
}
}
System.out.println("是否需要增加进程(1.YES/ELSE.NO)");//加入的进程先放入后备队列。
然后由后备队列自动的添加到就绪队列中
intchoose=sc.nextInt();
if(choose==1){
pi.PCBadd(poolQueue);
}
}
publicvoidwakeUp(){
System.out.println("请输入需要唤醒进程的ID号");
intid=sc.nextInt();
for(inti=0;iif(blockQueue.get(i).getPID()==id){
for(intj=0;jif(PCBready.get(j).getUseSource()==true){
PCBready.get(j).setUseSource(false);//解除j进程对临界资源占用。
以便让i进程进入就绪队列
}
}
PCBready.add(blockQueue.get(i));
blockQueue.remove(i);
}
}
}
}
packageos_check_1;
importjava.util.ArrayList;
publicclassMainStore{
staticArrayListmainStore=newArrayList();
MainStore(){
for(inti=0;i<10;i++){//设置主存大小为10.利用mainStore的大小表示主存。
mainStore.add(0);//构造未分分区表。
即设置所有的值为0。
值为1代表该内存被占用。
}
}
//得到某一块空闲分区的大小,并且占用。
将其置1
publicvoidGetEmpty(PCBPCB){
intfirst=0;
intlast=0;
for(inti=0;ilast++;
if(mainStore.get(i)==1||i==mainStore.size()-1){
if(last-first>=PCB.getSize()){
PCB.setFirstIndex(first);
System.out.println("进程"+PCB.getPID()+"进入主存");
PCB.setGetStore(true);
}else{
first=i;
}
}
}
if(PCB.isGetStore()==true){
inta=PCB.getFirstIndex();
intb=PCB.getSize();
for(;a
mainStore.set(a,1);//将被使用的主存置1
}
}
if(PCB.isGetStore()==false){
System.out.println("内存不足"+PCB.getPID()+"进程将被移入外存");
}
}
//释放空闲分区
publicvoidrelease(PCBPCB){
inta=PCB.getFirstIndex();
intb=PCB.getSize();
for(;a
mainStore.set(a,0);
}
System.out.println("进程"+PCB.getPID()+"释放内存"+PCB.getSize());
}
//内存不够时,移入外存。
进入外存队列
publicvoidmove(PCBPCB,ArrayListexternStore,ArrayListPCBready){
if(PCB.isGetStore()==false){
externStore.add(PCB);
PCBready.remove(PCB);
}
}
//内存何时够用
publicvoidcheck(ArrayListexternStore,ArrayListPCBready){
for(inti=0;iGetEmpty(externStore.get(i));//检查是否能够得到内存
if(externStore.get(i).isGetStore()==true){//得到内存时
PCBready.add(externStore.get(i));//将其再次加入就绪队列
System.out.println("进程"+PCBready.get(i).getPID()+"从外存进入内存");
}
}
}
publicvoidshow(){
System.out.println("主存使用情况为:
");
for(inti=0;iSystem.out.print(mainStore.get(i));
}
System.out.println();
}
}
packageos_check_1;
publicclassPCB{
privateintPID;//ID号
privateinttime;//一共所需的运行时间
privateintpriority;//优先级
privateintstate=0;//状态
//0-就绪1-执行
privatebooleansource=false;//占用的临界资源
privatebooleanuseSource=false;
//主存空间的分配和回收部分
privateintSize;
privateintfirstIndex;
privatebooleangetStore=false;
publicbooleanisGetStore(){
returngetStore;
}
publicvoidsetGetStore(booleangetStore){
this.getStore=getStore;
}
publicintgetSize(){
returnSize;
}
publicvoidsetSize(intsize){
Size=size;
}
publicintgetFirstIndex(){
returnfirstIndex;
}
publicvoidsetFirstIndex(intfirstIndex){
this.firstIndex=firstIndex;
}
publicintgetPID(){
returnPID;
}
publicvoidsetPID(intpID){
PID=pID;
}
publicintgetTime(){
returntime;
}
publicvoidsetTime(inttime){
this.time=time;
}
publicintgetPriority(){
returnpriority;
}
publicvoidsetPriority(intpriority){
this.priority=priority;
}
publicintgetState(){
returnstate;
}
publicvoidsetState(intstate){
this.state=state;
}
publicbooleangetSource(){
returnsource;
}
publicvoidsetSource(booleansource){
this.source=source;
}
publicbooleangetUseSource(){
returnuseSource;
}
publicvoidsetUseSource(booleanuseSource){
this.useSource=useSource;
}
publicvoidrun(){
if(priority>0){
this.priority--;
}
if(time>0){
this.time=time-1;
}
//System.out.println(PID+":
执行");
}
publicvoidgetAll(){
System.out.println("PID:
"+PID+"-"+time+"-"+priority+"-"+source);
}
}
packageos_check_1;
importjava.util.ArrayList;
importjava.util.Scanner;
publicclassPCBinit{
staticArrayListPCBready=newArrayList();
staticArrayListpoolQueue=newArrayList();
Scanner