****大学计算机学院
课 程 设 计
课 程 操作系统Ⅰ
题 目 进程管理
学 院 计算机学院
专 业 软件工程
班 级
姓 名
学 号
指导教师 ****
2019 年 6 月 16 日
目 录
1.设计目的与要求
1.1设计目的
1.2设计要求
2.设计思想及系统平台
2.1设计思想
2.2系统平台及使用语言
3.详细算法描述
4.源程序清单
5.运行结果与运行情况
6.总结
1.设计目的与要求
1.1设计目的
通过动态优先权算法的模拟加深对进程概念和进程调度过程的理解。
1.2设计要求
本实验要求学生独立地用C 或C++语言编写一个简单的进程管理程序,其主要部分是进程调度。调度算法可由学生自行选择,如基于动态优先级的调度算法。通过本实验可加深学生对进程各种状态的转化和各种调度算法的理解,提高系统程序设计能力。
2.设计思想及系统平台
2.1设计思想
1)当系统空闲(就绪队列为空)时,系统运行闲逛进程,否则运行其他进程,发生变迁1(就绪→运行)。
2)在运行进程(包括闲逛进程)的过程中,可能发生变迁2(运行→阻塞),即将运行进程插入到阻塞队列(闲逛进程不能被阻塞),可能有其他新的进程创建PCB,还可能唤醒阻塞队列中的某些进程PCB,发生变迁3(阻塞→就绪),即从阻塞队列中移出并插入就绪队列中。
(3)时间片运行结束后,若进程累计占用CPU时间大于等于进程需要运行的时间,则进程执行结束,释放其PCB。若进程累计占用CPU时间小于进程需要运行时间,发生变迁4(运行→就绪),即将当前运行的进程插入就绪队列中
2.2系统平台及使用语言
平台:Window10,codeblocks17.12
语言:c++
3.详细算法描述
用一个结构体PCB表示进程,进程中有一些变量具体含义看代码注释,我用一个PCB数组表示所有进程,根据题目对所有进程循环一遍表示一个时间片,在这个时间片里,如果进程的状态是在就绪队列里,它们的优先级加一,再用一个优先队列把就绪队列里的进程按优先级排列,如果在这个时间片里占用cpu的进程完成了,那么就从这个优先队列里取优先级最高的进入cpu运行;如果进程的状态是运行中(占用cpu),优先级减三如果完成了,就把状态置为完成,反之看看是否要进入阻塞队列了;总之就是再时间片内,做出相应变化,并在每个时间片后,输出各个进程的状态,直到所有的进程都结束。
4.源程序清单
#include <bits/stdc++.h>
#include <iostream>
#define FINAL 0
#define RUNNING 1
#define READY 2
#define BLOCK 3
using namespace std;
const int maxn=20;
int N;
struct PCB{
int id;//进程标识数
int priority;//进程优先级
int cputime;//进程已占用的CPU时间
int alltime;//进程还需占用的CPU时间
//当进程再运行STARTBLOCK个时间片后,进程将进入阻塞状态,startblocktmp为副本
int startblock,startblocktmp;
//已阻塞的进程再等待BLOCKTIME个时间片后,将转换成就绪状态,blocktimetmp为副本
int blocktime,blocktimetmp;
int state;//进程状态,FINAL完成,RUNNING运行,READY就绪,BLOCK阻塞
}p1,p2;
struct PCB P[maxn];
/*
struct cmp1{//最大值出
bool operator () (const PCB &p1,const PCB &p2) const{
return p1.priority<p2.priority;
}
};
struct cmp2{//最小值出
bool operator () (const PCB &p1,const PCB &p2) const{
return p1.blocktime>p2.blocktime;
}
};
priority_queue<PCB,vector<PCB>,cmp1 > que1;
priority_queue<PCB,vector<PCB>,cmp2 > que2;
set<int>ready;
set<int>block;
set<int>::iterator it;
*/
//按格式打印各个进程的状态
void show(int i){
cout<<"RUNNING PROG "<<i<<endl;
printf("READY_QUEUE:");
for(int i=0; i<N; i++){
if(P[i].state==READY) cout<<"->id"<<i;
}
cout<<endl;
printf("BLOCK_QUEUE:");
for(int i=0; i<N; i++){
if(P[i].state==BLOCK) cout<<"->id"<<i;
}
cout<<endl;
printf("===================================================\n");
printf("ID PRIORITY CPUTIME ALLTIME ");
printf("STARTBLOCK BLOCKTIME STATE \n");
for(int i=0; i<N; i++){
printf("%d\t%d\t%d\t",P[i].id,P[i].priority,P[i].cputime);
printf("%d\t%d\t%d\t",P[i].alltime,P[i].startblock,P[i].blocktime);
if(P[i].state==FINAL) cout<<"FINAL"<<endl;
else if(P[i].state==RUNNING) cout<<"RUNNING"<<endl;
else if(P[i].state==READY) cout<<"READY"<<endl;
else if(P[i].state==BLOCK) cout<<"BLOCK"<<endl;
}
}
void process_management(){
int n=0;//完成的进程数
int j=0;//第j个时间片
show(j);
int running=0;//1表示有程序正在运行,0表示没有
while(n!=N){
//int flag=0;
//优先队列que存就绪状态进程的优先级和对应的进程号
priority_queue<pair<int,int> > que;
//while(!que.empty()) que.pop();
//遍历所有进程(一个时间片),及在各个状态下的操作
for(int i=0; i<N; i++){
if(P[i].state==READY) {
P[i].priority+=1;
que.push(make_pair(P[i].priority,i));
}
else if(P[i].state==RUNNING) {
P[i].priority-=3;
P[i].cputime+=1;
P[i].alltime-=1;
P[i].startblocktmp--;
if(P[i].alltime==0) {//进程结束
P[i].state=FINAL;//结束标志
//flag=1;
running=0;
n++;//完成进程数加一
}
else if(P[i].startblocktmp<=0&&P[i].startblock>0) {//转为阻塞态
P[i].state=BLOCK;
P[i].blocktimetmp=P[i].blocktime;
running=0;
}
}
else if(P[i].state==BLOCK){
P[i].blocktimetmp-=1;
if(P[i].blocktimetmp<=0) P[i].state=READY;//转为就绪态
}
}
//当cpu空闲且就绪队列不为空时,取最大优先级的进程运行
if(( (!running))&&(!que.empty()) ){
pair<int,int> k=que.top();
int tmp=k.second;
P[tmp].state=1;
P[tmp].startblocktmp=P[tmp].startblock;
running=1;
}
show(++j);
}
}
int main()
{
printf("请输入进程数:\n");
cin>>N;
printf("请依次输入%d的初始值(进程从0~%d):\n",N,N-1);
printf("(0-结束状态(FIANL),1-运行状态(RUNNING),2-就绪状态(READY),3-阻塞状态(BLOCK))\n");
printf("ID PRIORITY CPUTIME ALLTIME ");
printf("STARTBLOCK BLOCKTIME STATE \n");
for(int i=0; i<N; i++){
cin>>P[i].id>>P[i].priority>>P[i].cputime>>P[i].alltime;
cin>>P[i].startblock>>P[i].blocktime>>P[i].state;
}
//P[n].state=1;
printf("进程运行过程中在各个时间片的状态\n");
process_management();
return 0;
}
5.运行结果与运行情况
运行过程中的部分截图:
6.总结
这里是引用由于理论课的局限性,让我不能很好地理解操作系统的一些算法思路,虽然只是模仿进程管理而做成的这个小程序,但是我从中不但明白了OS对进程调度的思想,还更好地加深对进程调度的理解,而不是单单地只是抽象概念。