【计算机专业】操作系统 先来先服务算法详解-精品文档资料整理.doc
1、 设计一个按先来先服务调度的算法 参考:山东专升本联盟 提示:(1)假设系统中有5个进程,每个进程由一个进程控制块(PCB)来标识。进程控制块内容如图1-1所示。进程名即进程标识。链接指针:按照进程到达系统的时间将处于就绪状态的进程连接成衣个就绪队列。指针指出下一个到达进程的进程控制块首地址。最后一个进程的链接指针为NULL。估计运行时间:可由设计者任意指定一个时间值。到达时间:进程创建时的系统时间或由用户指定。调度时,总是选择到达时间最早的进程。进程状态:为简单起见,这里假定进程有两种状态:就绪和完成。并假定进程一创建就处于就绪状态,用R表示。当一个进程运行结束时,就将其设置成完成态,用C表示。(2)设置一个队首指针head,用来指出最先进入系统的进程。各就绪进程通过链接指针连在一起。(3)处理机调度时总是选择队首指针指向的进程投入运行。由于本实验是模拟实验,所以对被选中进程并不实际启动运行,而只是执行:估计运行时间减1。用这个操作来模拟进程的一次运行,而且省去进程的现场保护和现场恢复工作。(4)在所设计的程序中应有显示或打印语句,能显示或打印正运行进程的进程名、已运行时间、还剩时间、就绪队列中的进程等。所有进程运行完成时,给出各进程的周转时间和平均周转时间。/* 实验一 先来先服务算法模拟程序* writen by daysky* 2007-11-19*/#include <iostream>#include <list>#include <string>#include <fstream>using namespace std;/控制块结构体struct PCBchar name;/进程名PCB *next;/链接指针int reach_time;/到达时间int left_time;/估计运行时间int begin_time;char status;/R就绪 c完成PCB();PCB(char aname,int areach_time,int aleft_time,int abegin_time=-1,char astatus='R',PCB *anext=NULL);PCB(const PCB &from);PCB:CB()next=NULL;reach_time = -1;left_time = -1;begin_time = -1;status = 'R'PCB:CB(char aname,int areach_time,int aleft_time,int abegin_time,char astatus,PCB *anext)name = aname;reach_time = areach_time;left_time = aleft_time;begin_time = abegin_time;status = astatus;next = anext;PCB:CB(const PCB &from)name = from.name;next = NULL;reach_time = from.reach_time;left_time = from.left_time;begin_time = -1;status = 'R'/* 先来先服务类*/class FirstServeprivate:int systime;/系统时间list<CB *> *ready_list,*all_task;/ 就绪队列 所有任务int together_time;ofstream fout;public:FirstServe();FirstServe(list<CB *> *a_all_task,const char *logfile);bool run();void check_task();void run_ready();void print_ready();FirstServe();FirstServe:FirstServe()systime=0;together_time = 0;ready_list=new list<CB *>();all_task=new list<CB *>();FirstServe:FirstServe(list<CB *> *a_all_task,const char *logfile)systime=0;together_time = 0;ready_list = new list<CB *>();all_task = a_all_task;fout.open(logfile,ios:trunc);/服务执行总调度bool FirstServe:run()int num = all_task->size();while(ready_list->empty()/添加新进程,同时从所有队列中删除刚添加的进程check_task();systime+;/运行直到有任务do/打印就绪队列print_ready();/执行就绪队列run_ready();systime+;check_task();while(!ready_list->empty();/打印平均周转时间fout << "平均周转时间为:" << together_time/num << "!" << endl;return true;/检查到达的任务,添加到就绪队列的尾部void FirstServe:check_task()PCB *current;list<CB *>:iterator it;it = all_task->begin();/这里用循环处理,因为可能有多个同时到达的任务while(it!=all_task->end()current=(*it);if(current->reach_time=systime)PCB *a_pcb = new PCB(*current);/复制进程信息a_pcb->status = 'R'ready_list->push_back(a_pcb);/添加在就绪队列的尾部it = all_task->erase(it); /从所有任务中删除这个任务fout << "进程" << a_pcb->name << "在时刻:" << systime << "进入就绪队列!" << endl;elseit+;/执行就绪队列,运行队列的第一个进程void FirstServe:run_ready()if(ready_list->empty() return;/就绪队列为空就不执行,否则PCB *front = ready_list->front();if(front->begin_time = -1)/进程第一次运行,设置运行起始时间front->begin_time = systime;front->left_time -;/执行一次,估计时间减一fout << "进程" << front->name << "执行在时刻:" << systime << "!" << endl;fout << "进程" << front->name << "已运行时间:" << (systime-front->begin_time+1)<< "!" << endl;fout << "进程" << front->name << "还剩时间为:" << front->left_time << "!" << endl;/当进程完成,改变进程的状态if(front->left_time = 0)front->status = 'C'/打印并计算周转时间,systime-1为完成时间fout << "进程" << front->name << "在时刻:" << systime << "结束!" << endl;int a_time = systime-1-front->reach_time;together_time += a_time;fout << "进程" << front->name << "的周转时间为:" << a_time << "!" <<endl;ready_list->pop_front();/删除第一个元素void FirstServe:print_ready()fout << "就绪队列中的进程有:"list<CB *>:iterator it=ready_list->begin();while(it!=ready_list->end()fout << (*it)->name << "、"it+;fout << endl;FirstServe:FirstServe()fout.close();int main()PCB *a_pcb5;list<CB *> *all_task=new list<CB *>();cout << "正在初始化." << endl;/五个进程的到达时间各不相同a_pcb0 = new PCB('A',9,10);a_pcb1 = new PCB('B',1,30);a_pcb2 = new PCB('C',3,25);a_pcb3 = new PCB('D',5,40);a_pcb4 = new PCB('E',2,33);for(int i=0;i<5;i+)all_task->push_back(a_pcb);FirstServe fs(all_task,"fcfs_log.txt");cout << "正在执行." << endl;fs.run();cout << "执行完毕!" << endl;return 0;