- 经验
- 17585
- 分贝
- 1819
- 家园分
- 25536
- 在线时间:
- 665 小时
- 最后登录:
- 2025-3-14
- 帖子:
- 5442
- 精华:
- 17
- 注册时间:
- 2006-5-25
- UID:
- 103781
注册:2006-5-25
|
<p>{<br/>void RunToBlk{PCBpp Run,PCBpp ABlkEd}<br/>[//定义运行态转为阻塞态。<br/>(*Run)->satate=blocked;<br/>*bLkEd=*Run;<br/>BlkEd++<br/>}</p><p>void RdytoRun(PCBpp &Rdy,PCBpp Run,Policy algthm)<br/>[//定义运行态转为阻塞态。<br/>if(algthm==hpf||algthm==spf)<br/>{<br/>if(*(Tdy+1))<br/>{<br/>(*(Rdy+1))->state=running;<br/>*Run=*(Rdy+1)<br/>Rdy++;<br/>}<br/>}<br/>else<br/>{<br/>if(*Rdy)<br/>(*Rdy)->state=running;<br/>*Run=*Rdy;<br/>Rdy++;<br/>}<br/>}<br/>}</p><p>void RunToRdy(PCBpp Run,PCBpp Rdy,PCBpp &RdyEd,Policy algthm)<br/>{//定义运行态转为就绪态。<br/>(*Run)->state=ready;<br/>*RdyEd=*Run;<br/>RdyEd++;<br/>if(algthm==hpf||algthm==spf)<br/>InsertSort(Rdy,RdyEd,algthm);<br/>}<br/>实验科目:计算机操作系统<br/>实验名称:进程调度模拟编程(实验四)<br/>一、实验目的<br/>通过对进程调度算法的模拟加深对进程概念和进程调度过程的理解。<br/>二、实验内容及仪器<br/>仪器:计算机,C++<br/>内容:用C语言、Pascal语言或其他开发工具实现对N(N=5)个进程的调度模拟,要求至少采用两种不同的调度算法(如简单轮转发Round Robin和优先权高者优先算法Highest Priority First),分别进行模拟调度。<br/> 每个用来标示进程的进程控制块PCB用结构(纪录)来描述根据需要,它包括以下字段:<br/> 进程表识数ID。<br/> 进程优先数Priority,并规定优先数越大的进程,其优先权越高。采用简单轮转法时该字段无用。<br/> 进程已经占用的CPU时间CPUTIME(以时间片为单位,下同)。<br/> 进程还需占用的CPU时间ALLTIME。当进程运行完毕时,ALLTIME变为0。<br/> 进程的阻塞时间STARTBLOCK,表示当进程再运行STARTBLOCK个时间片后,进程将进入阻塞状态。<br/> 进程被阻塞的时间BLOCKTIME,表示已经阻塞的进程再等待BLOCKTIME个时间片后,将转换成就绪状态。<br/> 进程状态STATE。<br/> 队列指针NEXT,用来将PCB排列成队列。<br/> 优先数改变的原则(采用简单轮转法时该字段无用);<br/> 进程在就绪队列中等待一个时间片,优先数增加1;<br/> 进程每运行一个时间片,优先数减3。<br/>假设在进行调度前,系统中有5个进程,它们的初始状态可以编程输入(更具有灵活性),也可以初始化为如下内容:<br/>ID PRIORITY CPUTIME ALLTIME STATEBLOCK STATE<br/>0 9 0 3 2 3 READY<br/>1 38 0 3 -1 0 READY<br/>2 30 0 6 -1 0 READY<br/>3 29 0 3 -1 0 READY<br/>4 0 0 4 -1 0 READY<br/> 为了清楚地观测诸进程的调度过程,程序应该将每个时间片内各进程的情况显示出来并暂停,参考格式如下:<br/>运行/Running:I<br/>就绪队列/Ready Queue:Idi,Idj,…<br/>阻塞队列/Block Queue:Idk,Idl,…<br/>=========================================================<br/>进程号 优先数 已运行时间 需要时间 开始阻塞时间 阻塞时间 状态<br/>0 P0 C0 A0 T0 B0 S0<br/>1 P1 C1 A1 T1 B1 S1<br/>2 P2 C2 A2 T2 B2 S1<br/>3 P3 C3 A3 T3 B3 S3<br/>4 P4 C4 A4 T4 B4 S4<br/> 三、实验结果和纪录<br/>//C++代码:<br/>#include "stdafx.h"<br/>#include<br/>using std::cout;<br/>using std::cin;<br/>using std::cerr;</p><p>enum Status{running,ready,blocked};<br/>enum Policy{fifo;spf,hpf,rr};</p><p>typedef class PCB<br/>{//定义PCB类。<br/>public:<br/>int id,priority,cputime,alltime startblock,blocktime;<br/>Status state;<br/>class PCB *next;<br/> CB()<br/>{<br/>priority=0;<br/>}<br/>}PCB,*PCBptr,**PCBpp;</p><p>char x;<br/> CBpp,pp;//两个全局变量</p><p>void Print(PCBptr head)<br/>{//打印head为头指针的PCB链表信息。<br/> CBptr p;<br/>cout<<*\n运行/Running:";<br/>for(p=head;p->next;p=p->next)<br/>{<br/>if(p->next->state==running)<br/>{<br/>cout<<"ID"<next->id;<br/>break;<br/>}<br/>}<br/>cout<<"\n就绪队列/Ready Queue:";<br/>for(p=head;p->next;p=p->next)<br/>if(p->next->state==blocked)<br/>cout<<"ID"<next->id<<'';</p><p>cout<<"\n--------------------------------------------\n"<br/><<" 进程号 优先数 已运行时间 还需要时间 开始阻塞时间 阻塞时间 状态\n";<br/>for(p=head;p->next;p=p->next)<br/>[<br/>cout<<" "<next->id<<" "<next->cputime<<" "<next->alltime"<br/> "<next->startblock<<" "<next->blocktime<<" ";<br/>switch(p->next->state)<br/>{<br/>case ready:cout<<"就绪";break;<br/>case running:cout<<"运行";break;<br/>case blocked:cout<<"阻塞";break;<br/>default:exit(0);<br/>}<br/>cout<<'\n';<br/>}<br/>cout<<"-----------------------------------------------\n"<br/><<"按任意键以继续...";<br/>cin>>x;<br/>}<br/>void Delete(PCBptr head,PCBptr p)<br/>{//删除以head为头指针的PCB链表中p所指向的结点。<br/> CBptr q=head;<br/>while(q->next!=p) q=q->next;<br/>delete p;<br/>}</p><p>void InsertSort(PCBpp Rdy,PCBpp RdyEd,Policy algthm)<br/>[//直接插入排序。<br/>if(*(Rdy+1))//队列不为空<br/>if(RdyEd-1!=Rdy+1)<br/>{//Ready+1队列中不只一个。<br/>switch(algthm)<br/>{<br/>case hpf;<br/>*Rdy=*(RdyEd-1);<br/>*(RdyEd-1)=*(RdyEd-2);<br/>for(tt=RdyEd-3;(*Rdy)->priority>(*tt)->priority;tt--)<br/>*(tt+1)=*tt;<br/>}<br/>break;<br/>case spf;<br/>if((*(RdyEd-1))->alltime<(*(RdyEd-2))->alltime)<br/>{<br/> CBpp tt;<br/>*Rdy=*(RdyEd-1);<br/>*(RdyEd-1)=*(RdyEd-2);<br/>for(tt=RdyEd-3;(*Rdy)->alltime<(*tt)->alltime;tt--)<br/>*(tt+1)=*tt;<br/>*(tt+1)=*Rdy;<br/>}<br/>}<br/>}<br/>}</p><p>void RunToBlk(PCBpp Run,PCBpp &BlkEd)<br/>{//定义运行态转为阻塞态。<br/>(*Run)->state=blocked;<br/>*BlkEd=*Run;<br/>BlkEd++;<br/>}</p><p>void RdyToRun(PCBpp &Rdy,PCBpp Run,Policy algthm)<br/>{//定义就绪态转为运行态。<br/>if(algthm==hpf||algthm==spf)<br/>{<br/>if(*(Rdy+1))<br/>{<br/>(*(Rdy+1))->state=running;<br/>*Run=*(Rdy+1);<br/>Rdy++;<br/>}<br/>}<br/>else<br/>{<br/>if(*Rdy)<br/>{<br/>(*Rdy)->state=running;<br/>*Run=*Rdy;<br/>Rdy++;<br/>}<br/>}<br/>}</p><p>void RunToRdy(PCBpp,Run,PCBpp Rdy,PCBpp &RdyEd,Policy algthm)<br/>{//定义运行态转化为就绪态。<br/>(*Run)->state=ready;<br/>*RdyEd=*Run;<br/>RdyEd++;<br/>if(algthm==hpf||algthm==spf)<br/>InsertSort(Rdy,RdyEd,algthm);<br/>}<br/>//以下是主程序<br/>int main()<br/>{<br/>cout<<"***************实验开始****************\n\n需要做几个进程并发执行的实验?;<br/>int n;<br/>if(!(cin>>n)) {cerr<<"错误:输入不准确!";exit(0);}</p><p>PCBptr Listhead,Listp,Listq;//建立n个进程<br/>Listhead=new PCB;//<br/>Listp=Listhead;//<br/>for(int i=0;i<=n-1;i++)//<br/>{<br/>Listq=new PCB;//<br/>Listp->next=Lisq;//<br/>Listp=Listq;//<br/>}<br/>Listp->next=0;//PCB的队列。</p><p>Policy algorithm;<br/>int num1,num2;<br/>L1:cout<<"\n请选择算法 (0表示FIFO,1表示SPF,2表示HPF,3表示RR):";<br/>if(!(cin>>num1)) {cerr"错误:出入不准确!";exit(0);}<br/>algorithm=Policy(num1);<br/>if(algorithm!=fifo&&algorithm!=spf&&algorithm!=hpf&&algorithm!=rr)<br/>{cout<<"无效的算法不真确!请重新输入:\n";goto L1;}<br/>cout<<"\n现在有"<个进程,首先我们初始化他们的PCB:\n\n";<br/>Listp=Listhead->next;<br/>for(int i=0;i<=n-1;i++)<br/>{<br/>cout<<"请输入"<号进程的PCB:\n"<br/>Listp->id=1;<br/>if(algorithm==hpf)<br/>{<br/>cout<<" 优先数 (整数,值越大表明优先权越高):";<br/>if(!(cin>>Listp->priority)) {cerr<<" 错误:输入不正确!";exit(0);}<br/>}<br/>cout<<" 已占用CPU时间(整数,以时间片为单位):";<br/>if(!(cin>>Listp->cputime)) {cerr<<"错误:输入不正确!";exit(0);}<br/>cout<<" 还需占用CPU时间(整数,以时间片为单位 ):";<br/>if(!(cin>>Listp->cputime)) {cerr<<"错误:输入不正确!";exit(0)}<br/>cout<<" 开始阻塞时间(整数,以时间片为单位):";<br/>if(!(cin>>Listp->startblock)) {cerr<<"错误:输入不正确!";exit(0);}<br/>cout<<" 阻塞时间(整数,以时间片为单位):";<br/>if(!(cin>>Listp->blocktime)) {cerr<<"错误:输入不正确!";exit(0);}<br/>L2: cout<<" 进程状态 (0表示运行,1表示就绪,2表示阻塞):";<br/>if(!(cin>>num2)) {cerr<<"错误:输入不正确!";exit(0);}<br/>if(num2!=0&&num2!=2) {cout<<"状态不正确!请重新输入:\n";goto L2;}<br/>Listp->state=Status(num2);<br/>Listp=Listp->next;<br/>}</p><p>PCBpp Run=new PCBptr(); // 生成<br/>PCBPP Ready=new PCBptr[100];//<br/>for(int i=0;i<=99;i++) *(Ready+i)=0 // 运行<br/>PCBpp ReadyEnd=Ready;// 就绪<br/>PCBp Block=new PCBptr[100]; // 阻塞<br/>for(int i=0;i<=99;i++) *(Block+i)=0; //<br/>PCBpp BlockEnd=Block;// 队列</p><p>if(algorithm==hpf||algorithm==spf) ReadyEnd++; //如果是HPF算法 ,用直接插入排序*Ready是哨兵,Ready+1成为队头。<br/>for(Listp=Listhead;Listp->next;Listp=Listp->next)<br/>{//把初始化的进程放进各自队列<br/>switch(Listp->next->state)<br/>}<br/>case running:*Run=Listp->next;break;<br/>case ready;<br/>{<br/>*ReadyEnd=Listp->next;ReadyEnd++;<br/>if(algorithm==hpf||algorithm==spf)<br/>InsertSort(Ready,ReadyEnd,algorithm);<br/>break;<br/>}<br/>case blocked:*BlockEnd=Listp->next;BlockEnd++;break;<br/>}<br/>}</p><p>cout<<"\n现在这"<个进程开始并发执行...... (按任意键继续...)\n\n";<br/>cin>>x;</p><p>for(int time=1;Listhead->next;time++)<br/>{//开始并发执行。<br/>cout<<"\n第"<个时间片结束后:";</p><p>if(*Run)<br/>{//Run队列的变化。<br/>if(algorithm==hpf)<br/>(*Run)->priority-=3;<br/>(*Run)->cputime++;<br/>if((*Run)->alltime>0)<br/>(*Run)->alltime--;<br/>if((*Run)->starblock>0)<br/>(*Run)->startblock--;<br/>}<br/>if(algorithm==hpf)<br/>{//Ready+1队列的变化。<br/>if(*(Ready+1))<br/>for(pp=Ready+1;pp!=ReadyEd;pp++)<br/>(*pp)->blocktime--;<br/>}</p><p>Print(Listhead);</p><p>if(*Block)<br/>{<br/>pp=Block;<br/>while(pp!=BlockEnd)<br/>{//把已经阻塞好了的进程移到就绪队列。<br/>if((*pp)->blocktime==0)<br/>{<br/>(*pp)->state=ready;<br/>*ReadyEd=*pp;ReadyEnd++;<br/>if(algorithm==hpf||algorithm==spf)<br/>InserSort(Ready,ReadyEnd,algorithm);<br/>for(PCBpp ss=pp;ss!=BlockEnd;ss++)<br/>*ss=*(ss+1);<br/>BlokEnd--;<br/>}<br/>else pp++;<br/>}<br/>}</p><p>if(*Run)<br/>{<br/>if((*Run)->alltime==0)<br/>{//如果运行完了,把该进程撤消,并拿就绪队头的进程来运行。<br/>Delete(Listhead,*Run);<br/>RdyToRun(Ready,Run,algorithm);<br/>}<br/>else <br/>{//没运行完<br/>if((*Run)->startblock==0)<br/>{//如果该阻塞了,则放入阻塞队列,并拿就绪对头的进程来运行。<br/>RunToBlk(Run,BlockEnd);<br/>RdyToRun(Ready,Run,algorithm);<br/>}<br/>else<br/>{//如果没阻塞<br/>if(algorthm==hpf)<br/>{//在HPF算法下,比较现在运行的进程的优先权和*(Ready+1)的优先权的大小。<br/>if(*(Ready+1))<br/>if((*Run)->priority<(*(Ready+1))->priority)<br/>{//下台了。<br/>(*Run)->state=ready;<br/>*ReadyEnd=*Run;ReadyEnd++;<br/>InsertSort(Ready,ReadyEnd,algorithm);<br/>if(*(Ready+1))<br/>Ready++;<br/>}<br/>}<br/>}<br/>if(algorithm==rr)<br/>{//在rr算法下就加入就绪队尾。<br/>(*Run)->state=ready;<br/>*ReadyEnd=*Run;<br/>ReadyEnd++;<br/>if(*Ready)<br/>{<br/>(*Ready)->state=running;<br/>*Run=*Ready;<br/>Ready++;<br/>}<br/>}<br/>}<br/>}<br/>}<br/>else<br/>RdyToRun(Ready,Run,algorithm);<br/>}</p><p>return 0;<br/>}<br/></p><p></p><p></p><p></p><p></p><p>#include <stdlib.h></p><p>#include <windows.h></p><p> </p><p>#include "Reader-Writer.h"</p><p>#include "Semaphore.h"</p><p> </p><p>// 这是 Windows 下多线程工作的 P 操作</p><p>#define P(S) WaitForSingleObject(S, INFINITE)</p><p> </p><p>// 这是 Windows 下多线程工作的 V 操作</p><p>#define V(S) ReleaseSemaphore(S, 1, NULL)</p><p> </p><p>const int RN = 5; // 所有读者总数</p><p>const int WN = 3; // 所有写者总数</p><p> </p><p>HANDLE Sdoc; // 文档信号量——互斥量</p><p>HANDLE Sr; // 读者信号量——广义信号量</p><p> </p><p>HANDLE Scnt; // 保护 g_cntReader 的互斥量</p><p>int g_cntReader = 0; // 读者个数计数器</p><p> </p><p>// ##############+. Descripted By Tang Houjian [2003-9-26 20:10:49] .+##########</p><p>// | funcname : JustWait ( ) </p><p>// + note : 显示一些信息,让后等待</p><p>// | </p><p>// +-----------------------------------------------------------------+</p><p>// | ret val : void </p><p>// | </p><p>// + Parameter : </p><p>// | [ int ] - nReader 读者(写者)编号,读者>0,写者<0</p><p>// | [ int ] - min 操作等待的最短时间</p><p>// | [ int ] - max 操作等待得最长时间,实际等待的时间介于两者之间</p><p>// | [ LPCSTR ] - info 要显示的信息</p><p>void JustWait(int nReader, int min, int max, LPCSTR info)</p><p>// +-----------------------------------------------------------------+</p><p>{</p><p> // 等待时间的基本量,以毫秒表示</p><p> const int BASETIME = 1000;</p><p> </p><p> // 实际等待得时间</p><p> int wait_time = 0;</p><p> if (max==min) // 判断是为了避免 %0错误,注意取随机值</p><p> wait_time = min*BASETIME;</p><p> else</p><p> wait_time = rand()%(max*BASETIME-min*BASETIME) + min*BASETIME;</p><p></p><p><br/> // 最终显示的信息缓冲</p><p> char s_out[128];</p><p> </p><p> // 读者大于0,写者小于0</p><p> if (nReader > 0)</p><p> sprintf(s_out, "Reader [%d]: %s\n", nReader, info);</p><p> else</p><p> sprintf(s_out, "\tWriter [%d]: %s\n", -nReader, info);</p><p> </p><p> // 打印</p><p> printf(s_out);</p><p> </p><p> // 然后等待</p><p> Sleep(wait_time);</p><p>}</p><p> </p><p>// 这是主函数</p><p>void TryReaderAndWriter()</p><p>{</p><p> // 创建信号量 这是初值--+ +----这是最大信号量值</p><p> // | |</p><p> Sdoc = CreateSemaphore(NULL, 1, 1, "Document");</p><p> </p><p> // 一次最多允许 3 个读者读</p><p> Sr = CreateSemaphore(NULL, 3, 3, "ReaderNumber");</p><p> </p><p> // 他也是一个互斥信号量,初值为 1</p><p> Scnt = CreateSemaphore(NULL, 1, 1, "ReaderCounterProtect");</p><p> </p><p> // 线程句柄</p><p> HANDLE threads[RN+WN];</p><p> </p><p> // 创建读者线程,共有 RN 个读者</p><p> for (int i=0; i<RN; i++)</p><p> threads = CreateThread(0, 0, Reader, 0, 0, 0);</p><p> </p><p> // 创建写者线程,共有 WN 个写者</p><p> for (int j=0; j<WN; j++)</p><p> threads[j+RN] = CreateThread(0, 0, Writer, 0, 0, 0);</p><p> </p><p> WaitForMultipleObjects(RN+WN, threads, TRUE, INFINITE);</p><p>}</p><p> </p><p>// 读者线程</p><p>DWORD WINAPI Reader(LPVOID lpPara)</p><p>{</p><p> // 注意是静态变量,可以使每来一个读者增加一</p><p> static int reader_num = 1;</p><p> int i = reader_num ++;</p><p> </p><p> while (1)</p><p> {</p><p> JustWait(i, 1, 2, "I want to Read");</p><p> </p><p> // 读者未满</p><p> P(Sr);</p><p></p><p><br/> // 锁定读者计数器</p><p> P(Scnt);</p><p> printf("//: %d Readers in, [%d] in\n”, g_cntReader, i);</p><p> g_cntReader ++;</p><p> // 如果是第一个读者</p><p> if (g_cntReader == 1) </p><p> {</p><p> JustWait(i, 1, 2, "I am NUMBER-ONE!");</p><p> // 锁定文档</p><p> P(Sdoc);</p><p> printf("#----------[%d] <== Doc busy\n", i);</p><p> JustWait(i, 1, 2, "I have get the document");</p><p> }</p><p> // 解锁读者计数器</p><p> V(Scnt);</p><p> </p><p> // 读ing…………</p><p> JustWait(i, 2, 5, "I am reading...");</p><p> </p><p> JustWait(i, 1, 2, "I want to get out");</p><p> </p><p> // 锁定读者计数器</p><p> P(Scnt);</p><p> g_cntReader --;</p><p> // 如果是最后一个</p><p> if (g_cntReader == 0) </p><p> {</p><p> JustWait(i, 1, 2, "I am the LAST-ONE!");</p><p> printf("----------#[%d] ==> Doc free\n", i);</p><p> // 解锁文档</p><p> V(Sdoc);</p><p> }</p><p> printf("//: %d Readers Left, [%d] is out\n”, g_cntReader, i);</p><p> // 解锁读者计数器</p><p> V(Scnt);</p><p> </p><p> // 离开</p><p> V(Sr);</p><p> </p><p> JustWait(i, 5, 3, "Rest^^^^^^^^^^^^");</p><p> }</p><p> </p><p> return 0;</p><p>}</p><p>DWORD WINAPI Writer(LPVOID lpPara)</p><p>{</p><p> // 注意是静态变量,可以使每来一个写者减去一,注意初值是负值</p><p> static int g_cnt = -1; </p><p> int j = g_cnt --;</p><p> </p><p> while (1)</p><p> {</p><p> JustWait(j, 2, 4, "I want write...");</p><p> </p><p> // 锁定文档</p><p> P(Sdoc);</p><p> printf("\t#==========[%d] <== Doc busy\n", -j);</p><p> </p><p> // 写ing……</p><p> JustWait(j, 4, 3, "WRITING......");</p><p> </p><p> JustWait(j, 1, 2, "write over! Out");</p><p> printf("\t==========#[%d] ==> Doc free\n", -j);</p><p></p><p></p><p> // 解锁文档</p><p> V(Sdoc);</p><p> JustWait(j, 8, 4, "Rest~~~~~~~~~~~~~");</p><p> }</p><p> </p><p> return 0;</p><p>}</p><p>"Reader-Writer.h"和"Semaphore.h"头文件怎么编 非常感谢!!<br/></p><p></p>
|
|