1、操作系统概论实验指导书实验一 进程管理实验一 进程管理一、目的进程调度是处理机管理的核心内容。本实验要求编写和调试一个简单的进程调度程序。通过本实验加深理解有关进程控制块、进程队列的概念,并体会和了解进程调度算法的具体实施办法。二、实验内容及要求1、设计进程控制块PCB的结构(PCB结构通常包括以下信息:进程名(进程ID)、进程优先数、轮转时间片、进程所占用的CPU时间、进程的状态、当前队列指针等。可根据实验的不同,PCB结构的内容可以作适当的增删)。为了便于处理,程序中的某进程运行时间以时间片为单位计算。各进程的轮转时间数以及进程需运行的时间片数的初始值均由用户给定。2、系统资源(r1rw)
2、,共有w类,每类数目为r1rw。随 机产生n进程Pi(id,s(j,k),t),0=i=n,0=j=m,0=knext=NULL;elsewhile(p1-next!=NULL)p1=p1-next;p1-next=pi;pi-next=NULL;return(head);/对进程进行初始化,建立就绪队列、阻塞队列。void input()AnsiString str1;m=StrToInt (Form1-Edit1-Text); /读取要模拟的进程总数给mn=StrToInt (Form1-Edit2-Text); /读取需初始化进程数给na=StrToInt (Form1-Edit3-Te
3、xt); /读取A类资源的总数给ab=StrToInt (Form1-Edit4-Text); /读取B类资源的总数给bc=StrToInt (Form1-Edit5-Text); /读取C类资源的总数给ctime1Inteval=StrToInt(Form1-Edit6-Text); /读取时间片长度给time1IntevalForm1-Timer1-Interval=time1Inteval;r=m-n; /计算可随机产生的进程数为rfor(i=1;iid=i; str1+= 产生进程ID:;str1+=IntToStr(p-id);str1+=rn; p-ra=(random(a-3)+
4、3); str1+= 所需A类资源数:;str1+=IntToStr(p-ra);str1+=rn; p-rb=(random(b); str1+= 所需B类资源数:;str1+=IntToStr(p-ra);str1+=rn;p-rc=(random(c-2)+2); str1+= 所需C类资源数:;str1+=IntToStr(p-ra);str1+=rn; p-ntime=(random(5)+1); str1+= 所需时间片个数:;str1+=IntToStr(p-ntime);str1+=rn; p-rtime=0; p-next=NULL; if (a-(p-ra)=0)&(b-(
5、p-rb)=0)&(c-(p-rc)=0) /如果资源符合所需要求 /则写入就绪队列队尾(状态为W)a=a-(p-ra); /当前所剩A类资源数目b=b-(p-rb); /当前所剩B类资源数目c=c-(p-rc); /当前所剩C类资源数目p-state=W;hready=insert(hready,p); /将进程插入就绪队列/ifelse /如果资源不符合所需要求,则写入阻塞队列队尾(状态为B)p-state=B;hblock=insert(hblock,p); /ifstr1+= 当前进程状态:;str1+=(p-state);str1+=rn;str1+=rn;/forForm1-Mem
6、o1-Lines-Add(str1);/从链表起始地址开始输出该链表的内容void disp(PCB *head)PCB *p1; p1=head; AnsiString str2; if(head!=NULL) /链表非空 do str2+= ; str2+=IntToStr(p1-id);str2+= ; str2+=(p1-state);str2+= ; str2+=IntToStr(p1-ra);str2+= ; str2+=IntToStr(p1-rb);str2+= ; str2+=IntToStr(p1-rc);str2+= ; str2+=IntToStr(p1-ntime);
7、str2+= ; str2+=IntToStr(p1-rtime);str2+=rn; p1=p1-next; while(p1!=NULL); /不断输出进程的信息,直到链尾! /if else str2+=tt该 队 列 中 没 有 进 程!rn ; Form1-Memo1-Lines-Add(str2); /输出就绪队列和阻塞队列的信息void outputall()AnsiString str1,str2,str3;str3+=rn ;str3+= = = = = = = = = = = = = = = CPU时间片运行了: ;str3+=IntToStr(h);str3+= 次= =
8、 = = = = = = = = = = = = =rn;Form1-Memo1-Lines-Add(str3);str1+=*当 前 就 绪 队 列 的 信 息 ;str1+=*rn ;str1+=进程ID 进程状态 A资源数 B资源数 C资源数 需要时间片 已运行时间片;Form1-Memo1-Lines-Add(str1);disp(hready);str2+=*当 前 阻 塞 队 列 的 信 息;str2+=*rn ;str2+=rn;str2+=进程ID 进程状态 A资源数 B资源数 C资源数 需要时间片 已运行时间片;Form1-Memo1-Lines-Add(str2);disp
9、(hblock);/建立一个PCB结构体型的空链表PCB *increat(void) PCB *head; head=NULL; return(head);/运行就绪队列的头进程,运行一个时间片,轮转一个时间片,时间片轮转调度算法PCB *running(PCB *head)PCB *p1;p1=head;AnsiString str4;If (p1-next=NULL) head=increat();else head=p1-next; p1-state=R; /进程状态由就绪转向运行(p1-rtime)+; /已运行时间片数增加1h+;str4+= 当前正在运行的进程ID是: ;str4
10、+=IntToStr(p1-id);str4+= rn;str4+=进程ID 进程状态 A资源数 B资源数 C资源数 需要时间片 已运行时间片rn;str4+= ;str4+=IntToStr(p1-id);str4+= ;str4+=(p1-state);str4+= ;str4+=IntToStr(p1-ra);str4+= ;str4+=IntToStr(p1-rb);str4+= ;str4+=IntToStr(p1-rc);str4+= ;str4+=IntToStr(p1-ntime);str4+= ;str4+=IntToStr(p1-rtime);str4+= ;Form1-M
11、emo1-Lines-Add(str4);if(p1-ntime=p1-rtime) /如果已经运行的时间片到达所需次数,该进程结束 str4+=rnrnttID号为:; str4+=IntToStr(p1-id); str4+= 的进程已经完成!; Form1-Memo1-Lines-Add(str4); a=a+(p1-ra); b=b+(p1-rb); c=c+(p1-rc); free(p1); /释放当前指针 else /如果已经运行的时间片未到达所需次数,该进程运行一个时间片后进入就绪队列尾 p1-state=W; head=insert(head,p1); return(head
12、);/检测当前资源数目是否满足阻塞队列里进程的需求void testblock()PCB *p1,*p2;p1=hblock;p2=hblock;AnsiString str5;while(hblock!=NULL)&(p1!=NULL)if(a-(p1-ra)=0)&(b-(p1-rb)=0)& (c-(p1-rc)=0) /如果满足if(p1=hblock)hblock=p1-next;p1-state=W; hready=insert(hready,p1); /将阻塞的进程插入就绪队列a=a-(p-ra);b=b-(p-rb);c=c-(p-rc);str5=tID号为: ;str5+=
13、IntToStr(p1-id);str5+= 的进程由阻塞队列转入就绪队列!rn; p1=hblock; /if(p1=hblock) else p2-next=p1-next; p1-state=W; hready=insert(hready,p1); str5=tID号为: ; str5+=IntToStr(p1-id); str5+= 的进程由阻塞队列转入就绪队列!rn; p1=p2-next; /else /大if else p2=p1; p1=p1-next; /else Form1-Memo1-Lines-Add(str5); /whlie/检测是否有新的进程产生,随机产生新进程v
14、oid testnew()int t;AnsiString str6;if(r0) /r=m-n为可随机产生的进程数目t=random(9); /生成随机数if(tid=i+; /i为全程变量,表示进程号?str6+=进程ID:;str6+=IntToStr(p-id);str6+=rn;p-ra=(random(a-3); /随机分配资源str6+=所需A类资源数:;str6+=IntToStr(p-ra);str6+=rn;p-rb=(random(b-3);str6+=所需B类资源数:;str6+=IntToStr(p-rb);str6+=rn;p-rc=(random(c-3);str
15、6+=所需C类资源数:;str6+=IntToStr(p-rc);str6+=rn;p-ntime=(random(5)+1); /随机分配时间片总数str6+=所需时间片个数:;str6+=IntToStr(p-ntime);str6+=rn;p-rtime=0; /已运行时间片数初始为0p-next=NULL;if (a-(p-ra)=0)&(b-(p-rb)=0)&(c-(p-rc)=0) /进程满足要求,进入就绪队列a=a-(p-ra); /分配资源给该进程,总资源数减少b=b-(p-rb);c=c-(p-rc);p-state=w;str6+=当前进程状态:;str6+=(p-sta
16、te);str6+=rn;hready=insert(hready,p);str6+=资源满足新进程需求,该进程进入就绪队列!;/ifelse /进程不满足要求,进入阻塞队列p-state=B;hblock=insert(hblock,p);str6+=当前进程状态:;str6+=(p-state);str6+=rn;str6+=资源不能满足新进程需求,该进程进入阻塞队列! ;/else/if (tMemo1-Lines-Add(str6); /if(r0)r-;/系统三类资源变化情况的显示void rescore() if(aa1) Form1-Edit7-Text=IntToStr(a1)
17、; if(aEdit7-Text=0; if(a=0&aEdit7-Text=IntToStr(a); if(bb1) Form1-Edit8-Text=IntToStr(b1); if(bEdit8-Text=0; if(b=0&bEdit8-Text=IntToStr(b); if(cc1) Form1-Edit9-Text=IntToStr(c1); if(cEdit9-Text=0; if(c=0&cEdit9-Text=IntToStr(c); /时间片轮转调度算法(先来先服务FCFS算法)void runFcfs() AnsiString str;if(form1_hready!=
18、NULL) /如果就绪队列为非空,则不断运行,直到就绪队列为空为止outputall(); /输出就绪队列和阻塞队列的信息form1_hready=running(form1_hready); /将就绪队列的第一个进程运行一个时间片testblock(); /检查阻塞队列是否有进程可以进入就绪队列testnew(); /检查是否有新进程产生rescore() ; /系统三类资源变化情况的显示elseForm1-Timer1-Enabled=false;Form1-Edit7-Text=IntToStr(a1);Form1-Edit8-Text=IntToStr(b1);Form1-Edit9-
19、Text=IntToStr(c1);str+=rnrn;Form1-Memo1-Lines-Add(str);/计时器触发时间片轮转调度算法void _fastcall TForm1:Timer1Timer(TObject *Sender)runFcfs(); /调度算法/将结果保存成txt文件void _fastcall TForm1:N8Click(TObject *Sender) if(Form1-SaveDialog1-Execute() FILE* fp=fopen(Form1-SaveDialog1-FileName.c_str(),w); if(fp=NULL) MessageB
20、ox(NULL,打开文件出错,信息,MB_OK); return; for(int i=0;iMemo1-Lines-Count;i+) fputs(Form1-Memo1-Lines-Stringsi.c_str(),fp); fputc(n,fp); fclose(fp);/开始模拟按钮单击执行函数void _fastcall TForm1:Button1Click(TObject *Sender) runmain(); Form1-Button1-Enabled=false; Form1-Edit1-Enabled=false; Form1-Edit2-Enabled=false; Fo
21、rm1-Edit3-Enabled=false; Form1-Edit4-Enabled=false; Form1-Edit5-Enabled=false; Form1-Edit6-Enabled=false;/清除屏幕按钮单击执行函数void _fastcall TForm1:Button2Click(TObject *Sender) Form1-Memo1-Clear(); Button1-Enabled=true; h=0; Form1-Edit1-Enabled=true; Form1-Edit2-Enabled=true; Form1-Edit3-Enabled=true; Form
22、1-Edit4-Enabled=true; Form1-Edit5-Enabled=true; Form1-Edit6-Enabled=true;/运行的主函数void runmain() AnsiString str,str1;input(); /对进程进行初始化,建立就绪队列、阻塞队列。Form1-Timer1-Enabled=true; /触发时钟,调用runFCFS,开始时间片轮转调度算法。str+=rn;3、运行界面和运行结果界面中,可以任意设定需要模拟的进程总数(如5),初始化进程个数(如3),还有A、B、C三类资源的总数(如10、10、10)。为了方便显示,还可以设定时间片的长度(如500毫秒)。除此之外,在运行过程中,所有的资源都是随机生成的,并且其中新进程的产生也是随机的,但是产生的进程总数不会多于开始设定的模拟的进程总数,以防止不断产生新进程,程序不断运行。在显示窗口的上方,还会实时显示资源的变化情况,方便对运行的观察。当运行结束后,可以通过工具栏中的显示选项中的保存结果按钮,将结果保存成txt文件格式,方便运行后的结果分析。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1