在采用多道程序设计的系统中,往往有若干个进程同时处于就绪状态。当就绪进程数大于处理器数时,就必须按照某种策略来进行进程调度,以决定进程占用处理器的次序。这里模拟设计一个在单处理器情况下的进程调度,按照优先级调度算法实现进程调度。
1.进程控制块及队列
假设有五个进程p1, p2, p3, p4, p5。进程的状态有就绪态(READY)、运行态(RUN)、完成态(FINISH)。每个进程的初始态都为READY。当一个进程运行结束后,它的状态为FINISH。
初始化是为每个进程确定他的优先级和要求运行时间,且按给定的优先级从高到低链成队列,用一单元指出对首进程,进程状态都为READY。
2.进程的运行
每次总是选择队首进程运行。可以采用动态改变优先级的办法,进程没运行一次就把优先级和要求运行时间减一。由于这是模拟进程调度,所以被选中运行的进程不必完成复杂的特定功能,而可以执行:
优先级 - 1
要求运行时间 - 1
来模拟进程的一次运行。
要提醒注意的是:在实际的系统中,当一个进程被选中运行时,必须回复进程现场,让它来占用处理器,知道等待时间或运行结束。这里省去了这些工作。
某进程的一次模拟运行结束后,若它的要求运行时间!=0,则需按照优先级从高到低调整队列。若它的要求运行时间=0,则撤销该进程,即把他的状态修改为FINISH,且退出队列。
若进程队列不为空,则再从首选进程运行,直到所有进程都运行结束。
具体的参考代码如下所示(由于涉及到操作系统底层的东西,所以采用C++或C编写比较方便)
#include<iostream> using namespace std; typedef struct node { char name[10]; // 进程名 int priority; // 优先级 int cputime; // 占用CPU时间 int needtime; // 到完成还要的时间 char state; // 状态 struct node *next; }PCB; PCB *finish, *ready, *run, *tail;
// 初始化进程 void init() { run = ready; run->state = 'R'; ready = ready->next; }
void print1() { cout << endl; cout << "进程名 占用CPU时间 到完成还要的时间 优先级 状态" << endl; }
void print2(PCB *q) { cout << q->name << "/t/t" << q->cputime << "/t/t" << q->needtime << "/t" << q->priority << "/t" << q->state <<endl; } // 输出结果 void print() { PCB *p; print1(); if(run != NULL) print2(run); p = ready; while(p != NULL) { print2(p); p = p->next; } p = finish; while(p != NULL) { print2(p); p = p->next; } getchar(); // 利用getchar()函数让程序调试运行结束后等待用户按下回车键才返回编辑界面 } // 插入进程 void insert(PCB *q) { PCB *p1,*s,*r; int b; s = q; p1 = ready; r = p1; b = 1; while((p1 != NULL) && b) { if(p1->priority >= s->priority) { r = p1; p1 = p1->next; } else b = 0;
} if(r != p1) { r->next = s; s->next = p1; } else { s->next = p1; ready = s; } } // 创建进程 void create(int n) { PCB *p; int i, time, priority; char na[10]; ready = NULL; finish = NULL; run = NULL; cout << "输入进程名及其需要运行的时间和优先级:" << endl; for(i = 1; i <= n; i++) { p = new PCB; cin >> na; cin >> time; cin >> priority; strcpy(p->name, na); p->cputime = 0; p->needtime = time; p->state = 'w'; p->priority = priority; if(ready != NULL) insert(p); else { p->next = ready; ready = p; } cout<<"输入进程名及其需要运行的时间和优先级:"<<endl; } print(); run = ready; ready = ready->next; run->state = 'R'; } // 处理进程 void process() { while(run != NULL) { run->cputime = run->cputime + 1; run->needtime = run->needtime - 1; run->priority = run->priority - 1; if(run->needtime == 0) { run->next = finish; finish = run; run->state = 'F'; run = NULL; if(ready != NULL) init(); } else if((ready != NULL) && (run->priority < ready->priority)) { run->state = 'W'; insert(run); init(); } print(); } } void main() { int n; cout << "输入进程的个数:"; cin >> n; create(n); process(); }
|
3.显示或打印执行情况
在所设计的程序中,应有显示或打印语句,能显示或打印每次被选中的进程名,运行一次后各进程控制块以及进程队列的变化。