模拟进程管理程序设计
一 设计目的与内容
1.1 设计目的
一个进程是一个程序对某个数据集的执行过程,是分配资源的基本单位。一个进程的生命期可以划分为一组状态,这些状态刻划了整个进程,系统根据PCB结构中的状态值控制进程,一个进程在并发过程中,由于资源共享与竞争,有时处于执行状态,有时,进程则因等待某种事件发生而处于等待状态,另外,当一个处于等待状态的进程因等待事件发生,被唤醒后,有因不可能立即得到处理及而进入就绪状态。因此,在进程的生命期内,一个进程至少具有三种状态:执行状态,等待状态和就绪状态。本课程设计要在VC++ 6.0的环境下,采用向量作为进程队列,通过设置定时器,运用时间片轮转法,实现进程在三个状态之间的切换,并动态显示每个队列的每个进程的当前状态。
1.2 设计内容
进程状态至少有运行,就绪和阻塞,相应设置运行队列、就绪队列、等待队列。 设计创建进程、撤销进程、调度进程、阻塞进程、唤醒进程函数执行相应功能。
调度算法可选:时间片轮转法、先来先服务、优先级等。
设计用户界面(可视化界面或键盘命令),以交互方式创建进程、撤消进程、调度
进程、阻塞进程、唤醒进程等功能。 能动态显示每个队列的每个进程的当前状态。
程序结构合理,运行稳定、界面友好、能检查操作错误,并给出错误信息。
二 设计方案
2.1 软件环境
Window XP操作系统
2.2 开发工具
用C++语言在VC++ 6.0开发环境下开发
2.3 开发思路
进程控制块用一个结构体来表示,程序内部设置一些系统资源,供创建的进程使用,
当需要创建一个进程时首先检验系统是否能够提供该进程需要的所有资源数量,如果能够满足,则进程创建成功,否则,创建失败并提示当前系统资源不足;系统初始化若干进程供用
1
周昌俊 龙慧鑫 牛言跃:模拟进程管理程序设计
户创建;用户只能从已初始化的进程中选择需要创建的进程;程序中用C++标准程序库(STL)中的向量(vector)创建相关进程队列,存放相应的运行进程、就绪进程和等待进程。调度算法选择时间片轮转法,通过设置一个定时器并设置相应的时间间隔来模拟进程运行的时间片的大小,如果一个进程在被调度选中之后用完了系统规定的时间片,但未完成要求的任务,则它自行释放自己所占有的CPU而排到就绪队列的末尾,等待下一次的调度。同时,进程调度程序又去调度当前就绪队列中的第一个进程。程序中设置一些事件来阻塞进程,当某些事件触发时,某个正在运行的进程就要释放占有的CPU而排到阻塞队列的末尾,等待某一个可以唤醒该进程的事件触发,当等待队列的进程所等待的事件发生时,等待该事件的所有进程都将被唤醒,并按次序排到就绪队列的末尾;进程运行结束或人为撤消时释放其所占有的资源,并从相应队列中删除。就这样,所有进程在定时器和调度算法的控制下井然有序地进行。
三 程序功能模块设计
3.1 进程控制块及资源管理模块
该模块中定义进程控制块的数据结构,新建三个类Source1、Source2和Source3代表三类系统资源,Source1中的一些成员函数用来管理资源的总数,使用数量和当前数量等; Source2和Source3均从Source1继承而来,三类资源的数量均在其构造函数中初始化。模块结构图如图1所示:
图1 进程控制块及资源管理模块结构图
3.2 进程初始化和队列管理模块
模块中初始化了五个进程供用户创建,设置了五个进程队列,分别用来表示运行队列
(RunList),就绪队列(ReadyList),等待队列(WaitList),系统已创建的进程队列(createdList),系统进程队列(sysProList),对应每个队列都有相应的队列管理函数,其中有添加进程到队列,从队列中撤消某个进程,从队列首部取出某个进程,从队列中取出某些进程(主要指阻塞队列),判断队列是否为空等。模块中还有一个函数,当系统退出时,调用该函数用来清空所有队列。模块的结构图如图2所示:
2
周昌俊 龙慧鑫 牛言跃:模拟进程管理程序设计
图2进程初始化和队列管理模块结构图
3.3 进程调度及用户接口模块
该模块对用户提供一些接口供用户使用,包括创建进程,撤消进程,显示各进程队列中
每个进程的情况等;同时随着时间片的开始与结束,根据实际情况来调度运行队列,就绪队列,阻塞队列,动态显示各队列的状态。模块中设置一个定时器,规定其时间间隔作为进程运行的时间片,进程调度过程在定时器的消息响应函数(OnTimer)中。模块中要用到进程控制块及资源管理模块、进程初始化和队列管理模块。模块的结构图如图3所示:
图3进程调度及用户接口模块结构图
3
周昌俊 龙慧鑫 牛言跃:模拟进程管理程序设计
3.4 三个模块层次图
三个模块的层次关系如图4所示:
图4 模块层次图
四 程序总控流程图
程序从创建进程开始,创建进程时,首先判断该进程是否存在于初始化进程队列中,如果不存在,则提示该进程不存在;如果存在,继续判断当前系统资源是否能够满足要创建的进程需要的资源,如果不满足,则提示等待其他进程运行完毕释放资源后再创建,如果满足,则创建成功,并将其添加到就绪队列中,同时启动定时器,取就绪队列的第一个进程加入到运行队列,并开始运行;运行过程中,要检查是否有被唤醒的进程,如果有,则将被唤醒的进程从阻塞队列中删除,同时添加到就绪队列末尾,如果没有,则判断当前进程是否运行完成,如果完成,则将运行进程从运行队列中删除,并释放资源,然后从就绪队列中取出第一个进程添加到运行队列,接着运行,如果没有运行完成,则继续运行,并判断当前运行的进程是否被阻塞,如果被阻塞,则将该进程从运行队列中删除,添加到阻塞队列末尾,同时从就绪队列中取出第一个进程添加到运行队列并运行,如果未被阻塞,则继续运行该进程,直至运行完成。程序的总控流程图如图5所示:
4
周昌俊 龙慧鑫 牛言跃:模拟进程管理程序设计
图5 程序的总控流程图
5
周昌俊 龙慧鑫 牛言跃:模拟进程管理程序设计
五 数据结构设计
5.1 PCB
进程控制块用一个结构体表示:
struct PCB{
CString identifier; CString username; Status status; int source1_num; int source2_num; int source3_num; int time_on_cpu; int need_cpu_time; };
说明:
Identifier: 进程名称 Username: 用户名称
Status: 进程状态(ready,run,wait) source1_num: 进程需要的资源1的数量 source2_num: 进程需要的资源2的数量 source3_num: 进程需要的资源3的数量 time_on_cpu: 进程需要运行的时间 need_cpu_time:进程还需要多少时间运行完成
5.2进程队列
进程队列采用C++标准程序库中的向量vector创建,共创建五个进程队列:
vector vector RunList :运行队列 ReadyList :就绪队列 6 周昌俊 龙慧鑫 牛言跃:模拟进程管理程序设计 WaitList :等待队列 sysProList :系统中所有进程队列 createdList :已创建进程队列 5.3 进程状态 枚举类型,列出进程的状态 enum Status{ready,wait,run,uncreate}; 说明: ready :进程处于就绪状态 wait :进程处于阻塞状态 run :进程处于运行状态 uncreate :进程尚未创建 六 程序代码结构 6.1 pcb.h 该头文件中包含了进程控制块的定义,系统资源的初始化及管理。结构体PCB定义了进程控制块的一些必要属性,类Source1,Source2,Source3是三个类,代表系统的三种资源,其成员变量和成员函数分别定义了资源的总量,当前量,获取资源的剩余量等。 6.2 类AttempProcess 定义了进程队列,初始化系统进程,并设计了操作队列的函数,队列的所有操作都通过该类的对象调用。 6.3类AddProDlg 创建新进程 6.4 类KillProDlg 撤消进程 6.5 类COSDesignDlg 该类定义了一些接口,接收用户要求,并调用相应函数执行相应操作,包括创建进程,撤消进程等。 类Source1,Source2,Source3,AttempProcess是四个的类,COSDesignDlg提供给用户的创建进程接口执行时要调用AddProDlg中的函数,COSDesignDlg提供给用户的撤销进程接口执行时要调用KillProDlg中的函数,COSDesignDlg调度进程并动态显示各个进程队列的状态要调用AttempProcess中的相应函数;在AddProDlg和KillProDlg中要验证创 7 周昌俊 龙慧鑫 牛言跃:模拟进程管理程序设计 建或撤销的进程是否合法,要调用AttempProcess中的相应的数据结构。五个类的层次关系如图6所示: 图6 类的层次关系图 七 程序代码 核心代码 pcb.h //资源1 class Source1{ public: int total_count; //资源1总数量 int left_count; //资源1剩余数量 public: //构造函数,初始化资源1的总数量和剩余数量 Source1() { } this->total_count = 15; this->left_count = this->total_count; //获取资源1总数量 int getTotalCount() { 8 周昌俊 龙慧鑫 牛言跃:模拟进程管理程序设计 } return this->total_count; //修改资源1的剩余量 void setLeftCount(int used_count) { } this->left_count = this->total_count - used_count; //获取资源1的剩余量 int getLeftCount() }; //资源2 class Source2 : public Source1{ //构造函数,初始化资源2的总数量和剩余数量 public: }; //构造函数,初始化资源1的总数量和剩余数量 class Source3 : public Source1{ public: }; //进程状态 enum Status{ready,wait,run,uncreate}; Source3() { } this->total_count = 10; this->left_count = this->total_count; Source2() { } this->total_count = 10; this->left_count = this->total_count; { } return this->left_count; 9 周昌俊 龙慧鑫 牛言跃:模拟进程管理程序设计 //进程控制块 struct PCB{ CString identifier; CString username; Status status; int source1_num; int source2_num; int source3_num; int time_on_cpu; }; //定义进程队列 AttempProcess.h vector //初始化系统进程 AttempProcess.cpp void AttempProcess::InitProcess() { PCB pcb1; pcb1.identifier = \"process1\"; pcb1.source1_num = 3; pcb1.source2_num = 2; pcb1.source3_num = 4; pcb1.status = uncreate; pcb1.time_on_cpu = 10000; pcb1.need_cpu_time = pcb1.time_on_cpu; pcb1.username = \"zl\"; this->isCpuBusy = false; this->toWhere = \"\"; int need_cpu_time; 10 周昌俊 龙慧鑫 牛言跃:模拟进程管理程序设计 this->sysProList.push_back(pcb1); PCB pcb2; PCB pcb4; pcb4.identifier = \"process4\"; pcb4.source1_num = 5; pcb4.source2_num = 3; pcb4.source3_num = 6; pcb4.status = uncreate; pcb4.time_on_cpu = 14000; pcb4.need_cpu_time = pcb4.time_on_cpu; pcb4.username = \"zl\"; this->sysProList.push_back(pcb4); PCB pcb3; pcb3.identifier = \"process3\"; pcb3.source1_num = 1; pcb3.source2_num = 4; pcb3.source3_num = 6; pcb3.status = uncreate; pcb3.time_on_cpu = 10000; pcb3.need_cpu_time = pcb3.time_on_cpu; pcb3.username = \"zl\"; this->sysProList.push_back(pcb3); pcb2.identifier = \"process2\"; pcb2.source1_num = 2; pcb2.source2_num = 2; pcb2.source3_num = 3; pcb2.status = uncreate; pcb2.time_on_cpu = 12000; pcb2.need_cpu_time = pcb1.time_on_cpu; pcb2.username = \"zl\"; this->sysProList.push_back(pcb2); 11 周昌俊 龙慧鑫 牛言跃:模拟进程管理程序设计 } //创建进程 OSDesignDlg.cpp void COSDesignDlg::OnCreateProcess() { // TODO: Add your control notification handler code here int time =0 ; time++; PCB pcb5; pcb5.identifier = \"process5\"; pcb5.source1_num = 3; pcb5.source2_num = 7; pcb5.source3_num = 5; pcb5.status = uncreate; pcb5.time_on_cpu = 15000; pcb5.need_cpu_time = pcb5.time_on_cpu; pcb5.username = \"zl\"; this->sysProList.push_back(pcb5); AddProDlg dlg; if(dlg.DoModal() == IDOK) { for(int index = 0;index < attempProcess.sysProList.size();index++) { PCB pcb = attempProcess.sysProList[index]; if(pcb.identifier == dlg.m_processName) { if(source1.left_count < pcb.source1_num || source2.left_count < pcb.source2_num || source3.left_count < pcb.source3_num) { AfxMessageBox(\"资源不足,暂时无法创建进程,请等待其他进程释放 资源后再创建!\"); } 12 周昌俊 龙慧鑫 牛言跃:模拟进程管理程序设计 else { pcb.status = ready; //更新剩余资源量 source1.left_count -= pcb.source1_num; } //撤销进程 OSDesignDlg.cpp void COSDesignDlg::OnKillProcess() { // TODO: Add your control notification handler code here KillProDlg dlg; } if(time == 1) SetTimer(1,1000,NULL); } } } readystatu = true; attempProcess.pushcreatedList(pcb); attempProcess.pushReadyList(pcb); UpdateData(false); m_s1Left = source1.left_count; m_s2Left = source2.left_count; m_s3Left = source3.left_count; source2.left_count -= pcb.source2_num; source3.left_count -= pcb.source3_num; // int count = 0; bool isExist = false; 13 周昌俊 龙慧鑫 牛言跃:模拟进程管理程序设计 if(dlg.DoModal() == IDOK) { for(int index = 0 ;index < attempProcess.createdList.size();index++) { PCB pcb = attempProcess.createdList[index]; if(pcb.identifier==dlg.m_processName) { isExist = true; attempProcess.toWhere = \"\"; attempProcess.deletecreatedList(pcb); attempProcess.deleteReadyList(pcb); attempProcess.deleteRunList(pcb); attempProcess.deleteWaitList(pcb); //释放资源 source1.left_count += pcb.source1_num; source2.left_count += pcb.source2_num; source3.left_count += pcb.source3_num; //更新剩余资源 m_s1Left = source1.left_count; m_s2Left = source2.left_count; m_s3Left = source3.left_count; } //定时器响应函数:进程调度 void COSDesignDlg::OnTimer(UINT nIDEvent) } } if(isExist == false) { } AfxMessageBox(\"进程未创建,请确定后再输入!\"); readystatu = true; UpdateData(false); } 14 周昌俊 龙慧鑫 牛言跃:模拟进程管理程序设计 { // TODO: Add your message handler code here and/or call default CListBox * readylist = (CListBox*)GetDlgItem(IDC_READY_LIST); CListBox * waitlist = (CListBox*)GetDlgItem(IDC_WAIT_LIST); CListBox * runlist = (CListBox*)GetDlgItem(IDC_RUN_LIST); total_time += 1000; //阻塞进程 if(total_time == 8000) { } else { } if(attempProcess.WaitList.size() != 0) { } attempProcess.toWhere = \"toready\"; attempProcess.deleteWaitList(attempProcess.WaitList[0]); waitstatu = true; readystatu = true; attempProcess.toWhere = \"towait\"; attempProcess.deleteRunList(attempProcess.RunList[0]); waitstatu = true; //根据当前运行进程剩余运行时间判断是否运行结束 if(attempProcess.RunList.size() != 0) { attempProcess.RunList[0].need_cpu_time -= 1000; if(attempProcess.RunList[0].need_cpu_time <= -1000) { attempProcess.toWhere = \"\"; PCB pcb = attempProcess.RunList[0]; source1.left_count += pcb.source1_num; 15 周昌俊 龙慧鑫 牛言跃:模拟进程管理程序设计 source2.left_count += pcb.source2_num; source3.left_count += pcb.source3_num; m_s1Left = source1.left_count; m_s2Left = source2.left_count; m_s3Left = source3.left_count; UpdateData(false); attempProcess.deleteRunList(attempProcess.RunList[0]); runlist->ResetContent(); CString title = \"进程名 状态 运行时间 剩余时间 资源1数 量 资源2数量 资源3数量\"; } if(readystatu == true) { readylist->ResetContent(); CString title = \"进程名 状态 运行时间 剩余时间 资源1数量 } else { } attempProcess.toWhere = \"toready\"; attempProcess.deleteRunList(attempProcess.RunList[0]); readystatu = true; runlist->AddString(title); 资源2数量 资源3数量\"; readylist->AddString(title); for(int ready_index= 0;ready_index < attempProcess.ReadyList.size();ready_index++) item += FormatData(attempProcess.ReadyList[ready_index]); { CString item; CString status = \" ready\"; item += attempProcess.ReadyList[ready_index].identifier; item += status; 16 周昌俊 龙慧鑫 牛言跃:模拟进程管理程序设计 } } readylist->AddString(item); readystatu = false; //从就绪队列中取进程到运行队列 if(attempProcess.ReadyList.size() != 0 && attempProcess.RunList.size() ==0) { } attempProcess.toWhere = \"torun\"; attempProcess.deleteReadyList(attempProcess.ReadyList[0]); readystatu = true; for(int run_index = 0;run_index < attempProcess.RunList.size();run_index++) { } CString item; CString status = \" run\"; item += attempProcess.RunList[run_index].identifier; item += status; item += FormatData(attempProcess.RunList[run_index]); runlist->AddString(item); if(waitstatu == true) { waitlist->ResetContent(); CString title = \"进程名 状态 运行时间 剩余时间 资源1数量 资源2数量 资源3数量\"; waitlist->AddString(title); for(int wait_index = 0;wait_index < attempProcess.WaitList.size();wait_index++) { CString item; CString status = \" wait\"; item += attempProcess.WaitList[wait_index].identifier; item += status; 17 周昌俊 龙慧鑫 牛言跃:模拟进程管理程序设计 } item += FormatData(attempProcess.WaitList[wait_index]); waitlist->AddString(item); waitstatu = false; } //所有进程运行结束 if(attempProcess.RunList.size() == 0 && attempProcess.ReadyList.size() == 0 && attempProcess.WaitList.size() == 0) } { } CDialog::OnTimer(nIDEvent); KillTimer(1); 八 测试数据及测试结果 8.1 系统界面 18 周昌俊 龙慧鑫 牛言跃:模拟进程管理程序设计 8.2 创建进程1(process1) 8.3 动态显示process1运行状态 19 周昌俊 龙慧鑫 牛言跃:模拟进程管理程序设计 8.4 多个进程轮流使用时间片,进程队列动态变化过程 九 设计过程中遇到的问题及解决方法 1 dos界面下与用户的交互性不好,操作十分不灵活,于是采用了可视化的用户界面形式。 2 用MFC集合类创建进程队列,调试程序过程中,频繁出现内存泄漏的错误,花费了很长 时间也找不出错误的根源,换了一种数据类型,用STL的vector,安全可靠,从而解决了内存泄漏的问题,系统也更加稳定。 3 为了能够动态显示进程队列中各个进程的变化情况,采用了定时器,设置适当的时间间 隔,这样就可以清楚得看到所有进程的动态变换过程。 十 结论 10.1系统实现特点 本系统能根据用户创建的进程模拟分配和收回系统资源,并采用时间片轮转法对进程的调用实施监视和控制,基本完成了系统进程管理系统的总体要求,有创建进程,撤销进程,阻塞进程等模块,能较好地反映进程管理的一些主要功能及实现方法。但在一些细节方面还做得不够好,比如本系统未能完成用户自定义的进程实现情况。 20 周昌俊 龙慧鑫 牛言跃:模拟进程管理程序设计 10.2系统特点 本系统能动态显示每个队列的每个进程的当前状态,程序结构合理,用定时器实现时间片轮转是本系统调度算法的核心。 本系统还做到了界面友好,在动态显示进程运行情况方面做足了功夫,能检查操作错误, 并给出错误信息,然后正确地返回到正确的操作步骤。 10.3设计体会及收获 通过本次对系统进程管理的设计,让我们巩固了所学知识,并将其运用到了实际的开发过程中。虽然系统做得比较粗糙,但基本实现了功能,而且通过调试和测试完善了不少漏洞,为我们以后的工作打下了一定的实践基础。 本次课程设计还让我们加深了对“团队”的理解,在设计和实现中充分发挥了每个队员 的能力,这对我们以后的工作有很大的帮助。 十一 参考文献 [1] 张尧学,史美林 计算机操作系统教程第2版 清华大学出版社 2000年 [2] 张尧学 计算机操作系统教程第2版 习题与实验指导 2000年 [3] Nicolai M.Josuttis 著 侯捷/孟岩 译 C++标准程序库 2002年 [4] Jeff Prosise 著 北京博彦科技发展有限责任公司 译 MFC Windows程序设计 2007年 21
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- gamedaodao.com 版权所有 湘ICP备2022005869号-6
违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务