操作系统本来就是一门令人十分郁闷的课,学生想学好,但很难看懂,而老师又不好讲课,但看来学校的领导显然还没有意识到这点,还居然要咱们把进程的调度算法给写出来(真的很想给老师们一个good……)!虽然是一个比较简单的“带时间片的先来先服务”调度算法(而且是一个阉割版本),但对于编程能力不强、对操作系统原理不熟悉的同学仔来讲,仍然是一次华丽的绝杀,血雨腥风……
本来打算从网上随便copy一份过来应酬一下的,不过发现有些确实十分垃圾(至少我找到的那一份就是),完全看不出进程调度过程的执行就直接输出一些不知名的东西出来。看来,上天还是要我自己把残局收拾。最后,经过一整天的努力(……此部分省略了五千字……),终于写了一个出来了,如果不在此keep一份,恐怕对不起自己的辛勤付出吧(******不过顺顺哥应该不会也看到这个空间然后以为我的代码是抄袭的吧,有点担心哟,所以如果各位大哥大姐想要转载代码的话,请标明出处为http://hi.baidu.com/waltertan/blog/item/fec1ad802b8063df9023d9e4.html,谢谢******)?呵呵……星期五一早就要把全班每个人的实验册和报告交给顺顺哥了……又要做搬运工啦,哈哈。
代码如下:
#include<stdio.h>
#include<stdlib.h>
#define RUNNING 1//用RUNNING 表示进程处于运行态
#define WAIT 2//用wait表示进程处于就绪态
#define FINISH 3//用FINISH表示进程已经执行完毕
#define TIME_PIECE 5//用TIME_PIECE表示时间片大小
#define MAX_PROCESS_NUM 10//假定系统允许进程个数为10
int AX,BX,CX,DX,PC,PSW,TIME;//模拟寄存器
int run;//定义指向正在运行进程的进程控制块的指针
int pfree;//定义指向空闲进程控制块队列的指针
struct{
int head;
int tail;
}ready;//定义指向就绪队列的头指针head和尾指针tail
struct{
int name;//进程标识符
int status;//进程状态
int ax, bx, cx,dx;//进程现场信息,通用寄存器内容
int pc;//进程现场信息,程序计数器内容
int psw;//进程现场信息,程序状态字寄存器内容
int time;//进程每次申请的时间片大小
int totalTime;//执行进程需要的总时间
int remainingTime;//进程剩余的执行时间
int next;//下一个进程控制块的位置
}pcbarea[MAX_PROCESS_NUM];//定义模拟进程控制块区域的数组
//进程控制块初始化
void Init(){
int i;
run=ready.head=ready.tail=-1;//运行指针、就绪指针清空
pfree=0;//空闲指针指向第一个进程
for(i=0;i<MAX_PROCESS_NUM-1;++i)
pcbarea[i].next=i+1;
pcbarea[MAX_PROCESS_NUM-1].next=-1;
}
//创建进程
void Create(int process_name,int ax,int bx,int cx,int dx,int pc,int psw,int totalTime){
int i;
if(pfree==-1){
//空闲进程控制块队列为空
printf("无空闲进程控制块,进程创建失败\n");
return;
}
i=pfree;//取空闲进程控制块队列的第一个
pfree=pcbarea[pfree].next;//pfree后移
//填写该进程控制块内容
pcbarea[i].name=process_name;
pcbarea[i].status=WAIT;
pcbarea[i].ax=ax;
pcbarea[i].bx=bx;
pcbarea[i].cx=cx;
pcbarea[i].dx=dx;
pcbarea[i].pc=pc;
pcbarea[i].psw=psw;
pcbarea[i].time=TIME_PIECE;
pcbarea[i].totalTime=totalTime;
pcbarea[i].remainingTime=totalTime;
if(ready.head!=-1){
//就绪队列不空时,置入就绪队列
pcbarea[ready.tail].next=i;
ready.tail=i;
pcbarea[ready.tail].next=-1;
}
else{
//就绪队列空时,置入就绪队列
ready.head=i;
ready.tail=i;
pcbarea[ready.tail].next=-1;
}
printf("\n");
}
//进程调度函数
void Sheduling(){
getchar();
if(ready.head==-1){
//空闲进程控制块队列为空,退出
printf("进程调度完毕!\n\n\n");
return;
}
run=ready.head;//就绪队列头指针赋给run,即让就绪队列的队头运行
ready.head=pcbarea[ready.head].next;//就绪队列头指针后移
if(ready.head==-1)
ready.tail=-1;//就绪队列为空,修正尾指针ready.tail
pcbarea[run].status=RUNNING;//修改进程控制块状态
//恢复该进程现场信息
AX=pcbarea[run].ax;
BX=pcbarea[run].bx;
CX=pcbarea[run].cx;
DX=pcbarea[run].dx;
PC=pcbarea[run].pc;
PSW=pcbarea[run].psw;
TIME=pcbarea[run].time;//设置相对时钟寄存器的时间片
//打印进程以及系统的状态信息
printf("\n进程编号:%d\n",pcbarea[run].name);
printf("进程状态:运行\n");
printf("寄存器内容:\n");
printf("AX: %d\n",AX);
printf("BX: %d\n",BX);
printf("CX: %d\n",CX);
printf("DX: %d\n",DX);
printf("PC: %d\n",PC);
printf("PSW: %d\n",PSW);
printf("TIME:%d\n\n",TIME);
printf("\n**时间片用完**\n");
AX=BX=CX=DX=PC=PSW=TIME=0;//时间片用完立即归还CPU资源
//若进程执行完毕,则回收进程控制块
if(pcbarea[run].remainingTime<=TIME_PIECE){
getchar();
pcbarea[run].remainingTime=0;
pcbarea[run].status=FINISH;
ready.head=pcbarea[run].next;
//打印进程以及系统的状态信息
printf("\n进程编号:%d\n",pcbarea[run].name);
printf("进程状态:完成\n");
printf("寄存器内容:\n");
printf("AX: %d\n",AX);
printf("BX: %d\n",BX);
printf("CX: %d\n",CX);
printf("DX: %d\n",DX);
printf("PC: %d\n",PC);
printf("PSW: %d\n",PSW);
printf("TIME:%d\n\n",TIME);
//将该进程控制块置入空闲队列
if(pfree==-1){
pfree=run;
pcbarea[pfree].next=-1;
}
else{
pcbarea[pfree].next=run;
pfree=run;
pcbarea[run].next=-1;
}
}
//若进程还没执行完毕,则将其置入就绪队列,等待下次的时间片到来
else{
getchar();
pcbarea[run].remainingTime-=TIME_PIECE;
pcbarea[run].status=WAIT;
//将进程置入就绪队列中
if(ready.tail!=-1)
pcbarea[ready.tail].next=run;
else
ready.head=ready.tail=run;
pcbarea[run].next=-1;
ready.tail=run;
//打印进程以及系统的状态信息
printf("\n进程编号:%d\n",pcbarea[run].name);
printf("进程状态:等待\n");
printf("寄存器内容:\n");
printf("AX: %d\n",AX);
printf("BX: %d\n",BX);
printf("CX: %d\n",CX);
printf("DX: %d\n",DX);
printf("PC: %d\n",PC);
printf("PSW: %d\n",PSW);
printf("TIME:%d\n\n",TIME);
}
Sheduling();//如果还有进程没有执行完毕,则继续递归调度
}
void main(){
int process_name,ax,bx,cx,dx,pc,psw,totalTime;
int i;
char quit;//用于选择退出进程模拟系统
do {
i=MAX_PROCESS_NUM;
printf("==========================模拟单处理器系统的进程调度==========================\n\n\n");
Init();
printf("**创建进程,输入负数可结束创建**\n\n");
printf("输入一个进程的编号(现在还可以创建%d个进程):",i);
scanf("%d",&process_name);
while(process_name>0){
printf("请输入该进程中ax、bx、cx、dx、pc、psw的初始现场信息:");
scanf("%d%d%d%d%d%d",&ax,&bx,&cx,&dx,&pc,&psw);
printf("请输入该进程运行所需的总时间:");
scanf("%d",&totalTime);
Create(process_name,ax,bx,cx,dx,pc,psw,totalTime);
if(i>0)
--i;
printf("输入一个进程的编号(现在还可以创建%d个进程):",i);
scanf("%d",&process_name);
}
system("cls");
printf("请按回车开始调度……");
getchar();
Sheduling();
printf("退出请按0,重新测试请按任意键:");
quit=getchar();
system("cls");
} while(quit!='0');
printf("\n\n");
}