#define getpch(type) (type*)malloc(sizeof(type)) #define NULL 0
#define TIME 2//时间片长度 /////////////
typedef struct pcb{ //////进程管理块 char name[10];///////进程名字 char state; int queue; int ntime; int rtime; int etime;
///////进程状态
//////进程所在的队列 /////进程需要运行的时间 //////进程已经运行的时间 ////进程在本队列可运行的时间片
struct pcb *link; }PCB;
PCB *ready = NULL, *pinsert = NULL, *pfend = NULL,*p =NULL; 列,进程插入位置的变量*/
int geti() //使用户仅能输入整数 {
char ch; int i = 0; fflush(stdin); ch = getchar(); while(ch == '\\n'){ }
while(ch != '\\n'){
if(ch > '9' || ch < '0'){
printf(\"\输入有误!!输入只能为正整数,请重新输入...\\n\"); fflush(stdin); i = 0;
ch = getchar();
printf(\"\f输入不能为空..请重新输入\\n\"); fflush(stdin); ch = getchar();
/*就绪队
}
}else{ }
i = i*10 + (ch - '0'); ch = getchar();
return i; }
void findpos()///////更新状态量 {
PCB *ps = pfend;
if(!ps || !ps -> link || (ps-> link->queue - ps->queue) > 1)
pinsert = ps;
else{ } }
void insert()//////插入进程 {
if(!ready ){
ready = p; pfend = p; pinsert = p;
while (ps->link && ps ->link->queue != (pfend ->queue +2))
ps = ps->link;
pinsert = ps;
}else if(ready ->queue == 1) //////第一队列存在
{ } Else { } }
void input()/*建立进程控制块函数*/ {
int i,num;
printf(\"\\n请输入进程的个数:\"); num = geti();
for(i=0; i < num; i++) {
printf(\"\\n进程号No.%d:\\n\p=getpch(PCB);
printf(\"\\n输入进程名:\"); scanf(\"%s\
printf(\"\\n输入进程运行时间:\"); p ->ntime = geti(); p->link = ready; ready = p; findpos();
p->link = pfend->link; pfend->link = p; pfend = p; findpos();
} }
printf(\"\\n\"); p->rtime=0; p->state='w'; p->queue =1; p->etime = TIME; p->link=NULL;
insert();/*调用insert函数*/
void disp(PCB *pr)/*建立进程现实函数,用于显示当前进程*/ {
printf(\"\\nname\ state\ queue\ ntime\ rtime\在队列可停留时间\ \\n\"); printf(\"|%s\\ printf(\" |%c\\ printf(\" |%d\\ printf(\" |%d\\ printf(\" |%d\\ printf(\" |%d\\ printf(\"\\n\"); }
void check()/*建立进程查看函数*/ {
PCB *pr;
printf(\"\\n ****当前正在运行的进程是:%s\显示当前运行的进程*/
disp(ready); pr= ready ->link;
printf(\"\\n****当前就绪队列状态为:\\n\");/*显示就绪队列状态*/
while(pr!=NULL) { } }
void sort()//调整进程队列 {
if(!ready->link ||ready->queue < ready->link->queue) return;
p = ready ->link;
ready ->link = pinsert ->link; pinsert ->link = ready; pinsert = ready; ready = p;
if (ready && ready -> queue == pinsert ->queue){ } }
void addnew()//添加新的进程 {
if(ready ->queue != 1){ (ready -> queue)++; ready->etime *= 2; ready -> state='w';
findpos(); disp(pr); pr=pr->link;
sort();/*调用sort函数*/ input(); } else{ } }
void destroy()/*建立进程撤销函数(进程运行结束,撤销进程)*/ {
printf(\"\\n进程[%s]已完成.\\n\ p = ready;
ready = ready->link; free(p);
if (ready && ready -> queue == pinsert ->queue) }
void running()/*建立进程就绪函数(进程运行时间到,置就绪状态)*/ {
(ready -> rtime)++; ready ->etime --;
if(ready->rtime == ready->ntime){
destroy(); return; findpos(); input();
}else if(ready ->etime == 0){
int time = 2; (ready -> queue)++;
} }
for(int i = 2; i != ready->queue; ++i)
time *= 2;
ready->etime = time; ready -> state='w'; sort();/*调用sort函数*/
void main() {
char ch; input();
while(ready != NULL) { }
printf(\"\\n\\n 进程已经完成\\n\"); getchar(); }
printf(\"\\nThe execute name:%s\\n\ready ->state = 'R'; check(); running();
printf(\"\\n按i键添加新进程....按其他任意键继续运行...\"); fflush(stdin); ch = getchar();
if (ch == 'i'|| ch=='I')
addnew();
运行结果如下: 根据题意输入五个进程
按任意键继续
四、实验问题及原因
(1)本次试验,思路设计不难在这个多级反馈的实验中,我采取了用一条实际上的链表队列来模
拟多个逻辑上的队列,通过维护几个链表的状态信息来找到每个进程运行完后应该插入的地方,还有一个标志位Fend用来表明新插入的队列的位置。
(2)在建立优先数就绪队列时主要运用,链表插入模型。但是由于本题是从建立、到完成一个就绪对列,所以必须分多种情况讨论。 五、实验体会和收获
(1)本次试验后对优先数调度算法和时间片轮转调度算法实现的过程,有了很清楚的认识、理解。设计计数器来对进程执行状态的时间分析,使得进程调度这一抽象模型得到具体化。之后,便是对进程的插入(执行完,插入到完成队列,否则插入到就绪)和再次调度(当改进程再次满足条件时,从就绪队列调度到执行队列)重复过程。 (2)通过设计PCB结构,模拟进程调度,加深了对进程的理解。 (3)提高了C语言编程动手能力