实 验 报 告
课程名称
计算机操作系统
实验项目
作业/进程调度算法设计与实现
实验仪器
院 系 计算机学院
专 业 计算机科学与技术
班级/学号 计 0503 / 29
学生姓名 杨天心
实验日期
2007-11
成 绩
指导老师
计算机操作系统
计 0503 杨天心 29
实验二 作业/进程调度算法设计与实现
一.实验目的
调度是操作系统的主要功能,本实验通过自行设计实现的调度程序,使同学们加深
对作业/进程调度功能的理解,从而掌握操作系统的基本原理。同时还可以提高同学们
的编程能力。
二.实验要求
用 C 语言编制按优先级调度三个进程的调度程序,其中要求进程的优先级随着运
行时间的延长而降低,但却随着等待时间的延长而升高。
三.实验方法内容
(一)算法设计的思路
1、 设计进程控制块为以下结构:
struct PRO
﹛
/*进程的 id 号,可以表示为 a, b, c */
/*进程的初始优先级*/
/*等待进程可以动态增加的优先级量*/
/*运行进程应该动态减少的优先级量*/
char id;
int pri;
int p;
int s;
int status; /*表示进程的状态,0 为等待,1 为运行*/
﹜A={‘a’,2,1,1,0},B={‘b’,1,1,1,0}, C={‘c’,0,1,1,0};
2、 要求接管时钟中断:INT 1Ch
使用到的 C 语言函数为:
getvect(intno)
setvect(intno,time)
/*获得 intno 的中断向量*/(要求保存在一个全局变量中)
/*设置 intno 的中断向量为函数 time 的入口地址*/
3、 在自己编制的新的时钟中断处理程序中,完成进程优先级的修改;并记录被中断的
次数。
Void interrupt time( )
{
if(A.status==1) A.pri=A.pri-A.s;
else
A.pri=A.pri+A.p;
……..
…….
xx++;
}
计算机操作系统
计 0503 杨天心 29
4、 编制函数 select( ),其功能是从三个进程中选择优先级最高的进程,并将其状态设
置为运行,其余设置为等待。并返回运行进程的序号供主程序选择运行。
5、 编制函数 int prime (int n),功能是判断 n 是否为素数,如果是素数,返回 n;否则
返回 0。该函数是三个进程的执行过程。
6、 主程序框架如下:
main ( )
{ int a[3]={100,100,100};
int I, j, k, u, v, w=0, x=0, y=0;
char c;
/*获得时钟中断向量*/
/*设置新的中断向量*/
………..
while(xx<300)
/*xx 是全局变量,用于记录时钟中断的次数;用循环来模拟三个
进程的运行过程*/
/*调度一次*/
{u=select ( );
switch (u)
{case0: a[0]++; if(a[0]>10000) a[0]=100; v=prime(a[0]);
if(v) {gotoxy(2,4); printf(“a
%6d
%6d”, v, w++);} break;
case1:…………………..
case2:…………………..
}
}
/*恢复时钟中断*/
}
(二)题目理解说明:
从实验的题目可以看出本次实验的内容是在已经给定的结构上对程序进行补充完善。
通过对已给程序的分析,只需要完成时钟中断处理函数 time(),进程选择程序 select(),求素
数函数 prime()以及主函数中 switch 语句部分的程序编制即可。
(三)算法的功能框架流程图
(四)此算法中用到的数据结构:
进程实体结构,模拟 PCB:
Main()
struct PRO
{
char id;
int pri;
Time()
int p;
int s;
int status; //进程状态
/*进程 id 号 */
//进程优先级
/*优先级递增量*/
/*优先级递减量*/
}
C B A
中 断 到 达
选择进程
Select()
Prim()
计 0503 杨天心 29
计算机操作系统
(五)主要常量变量:
INTR:存放中断号 1ch 的常量
Xx:存放中断次数的全局变量
Oldhandler:指向原中断处理程序的向量
a[3]:对素数进行操作的数组空间
(六)主要模块:
1.中断处理函数
void interrupt time(...)
接管时钟中断,当中断到达时,对 A,B,C 三个进程数据结构中优先级 pri 进行修改。
对正在运行的程序,优先级减去一个递减量 s,对于未运行的程序,优先级增加一个的增量
p。处理完成后,中断次数 xx 加 1。
2.进程选择函数
char select()
根据进程的优先级进行选择。选出优先级最高的进程,将其状态 status 设置为 1,即为
该进程分配处理机,投入运行,返回该进程的进程号 id。将其他进程状态 status 设置为 0,
即剥夺处理机或不为其分配处理机。此函数模拟对 PCB 的操作。
3 求素数函数
int prime (int n)
用于判断 n 是否为素数。通过循环依次用从 2 到 n 的平方根对 n 取模。如果能被除尽,
余数为零。跳出循环,返回 0。如果始终没被除尽,表明 n 为素数,返回 n。
4.主函数
void main ( )
首先定义 所需要的变量,数组。获取中断,并将中断处理程序设置到 time()函数上。
输出提示信息后。便开始模拟进程调度过程。
通过 select()函数取得优先级最高的进程号。通过 switch 语句判别进程号,选中三个模
拟的循环求素数进程的程序体中的一个,执行其中的内容,输出信息。
如果中断次数 xx 小于 300 次,则继续调用 select()函数选出进程并执行,直至满足这个
条件。
最后恢复系统原有的中断处理程序。
四.实验代码:
ex2.c
//====================================================================
#include
#include
#include
#include
#define INTR 0x1C
//INT 1Ch
计算机操作系统
计 0503 杨天心 29
//记录中断次数的全局变量
//定义中断向量
/*进程 id 号 */
//进程优先级
/*优先级递增量*/
/*优先级递减量*/
int xx=0;
void interrupt (*oldhandler)(...);
//进程控制块结构体
struct PRO
{
char id;
int pri;
int p;
int s;
int status; //进程状态
}A={'a',2,1,1,0},B={'b',1,1,1,0},C={'c',0,1,1,0};
//中断处理函数
void interrupt time(...)
{ int a;
if(A.status==1) A.pri=A.pri-A.s;
else
A.pri=A.pri+A.p;
if(B.status==1) B.pri=B.pri-B.s;
else
B.pri=B.pri+B.p;
if(C.status==1) C.pri=C.pri-C.s;
else
C.pri=C.pri+C.p;
xx++;
}
/*进程选择函数*/
char select()
{if(A.pri>=B.pri&&A.pri>=C.pri) {A.status=1;B.status=0;C.status=0;return A.id;}
else if(B.pri>A.pri&&B.pri>=C.pri) {A.status=0;B.status=1;C.status=0;return B.id;}
else {A.status=0;B.status=0;C.status=1;return C.id;}
}
/* 求素数函数*/
int prime (int n)
{int k,i,j;
k=sqrt(n);
for(i=2;i<=k;i++)
if(n%i==0) return 0;
return n;
}
//主函数
void main ( )
{ int a[3]={100,100,100};
int u, v, w=0, x=0, y=0;
char c;
oldhandler=getvect(INTR);
setvect(INTR,time);
gotoxy(10,2); printf("THE PROCESSES ARE PLAYING:\n");
gotoxy(10,4); printf("Processid
/*将中断处理函数设为 time()*/
/*获取中断处理 INT 1Ch*/
Prime
Times\n");
计算机操作系统
while(xx<=300)
{u=select();
计 0503 杨天心 29
switch (u)
{
case 'a': a[0]++; if(a[0]>10000) a[0]=100; v=prime(a[0]);
if(v) {gotoxy(10,6); printf("
A
%6d
%6d", v, w++); } break;
case 'b': a[1]++; if(a[1]>10000) a[1]=100; v=prime(a[1]);
if(v) {gotoxy(10,8); printf("
B
%6d
%6d", v, x++); } break;
case 'c': a[2]++; if(a[2]>10000) a[2]=100; v=prime(a[2]);
if(v) {gotoxy(10,10); printf("
C
%6d
%6d", v, y++); } break;
}
gotoxy(13,12); printf("TIME INTERRUPT %d",xx);
}
setvect(INTR,oldhandler);
getchar();
}
//================================================================
/*恢复中断*/
五.执行结果:
(一)结果截图:
(二)结果分析:
程序执行结果中 process id 代表了每个参与调度的进程号,prime 为进程的程序体即求
素数过程在最后一次执行时所求得的那个素数。Times 中的数据为各个进程各自得出的素数
的个数的总数。Time interrupt 后的值为程序执行过程中中断的次数。该结果正好符合题目要
求,达到了实验的目的。
六.用户操作指南:
本程序没有过多涉及人机交互的处理,在程序调试通过并编译链接之后,只需要直接执
行便可看到演示的过程和最终结果。
计算机操作系统
七.实验总结:
计 0503 杨天心 29
首先,通过本次实验加深了我对于作业/进程调度功能的认识,并且更加深刻地理解了
操作系统中进程调度的基本原理。
本次实验中用到的有关中断处理函数及返回类型信息是通过 Turbo C 帮助文档获得的。
这种经历使我对怎样通过使用程序的联机帮助文档来有查阅自己需要的信息有了更深刻的
认识。
八.所有的源程序清单
ex2.c :程序主文件