操作系统实验 (第一次)
一、实验内容
选择一个调度算法,实现处理器调度。
二、实验目的
在采用多道程序设计的系统中,往往有若干个进程同时处于就绪状态。当就绪状态进程 个数大于处理器数时,就必须依照某种策略来决定哪些进程优先占用处理器。本实验模拟在 单处理器情况下处理器调度,帮助学生加深了解处理器调度的工作。
三、实验题目
第二题:设计一个按时间片轮转法实现处理器调度的程序。 [提示]
(1)假定系统有五个进程,每一个进程用一个进程控制块PCB 来代表。进程控制块的格 式为: 进程名 时间
要求求运行时间 优先数 状态
其中,进程名----作为进程的标识,假设五个进程的进程名分别是Q 1,Q 2,Q 3,Q 4,Q 5。 指针----进程按顺序排成循环队列,用指针指出下一个进程的进程控制块首地址,最 后一个进程中的指针指出第一个进程的进程控制块首地址。 要求运行时间----假设进程需要运行的单位时间数。
已运行时间----假设进程已经运行的单位时间数,初始值为“0”。
状态----有两种状态,“就绪”状态和“结束“状态,初始状态都为“就绪“,用“R ” 表示,当一个进程运行结束后,它的状态变为“结束”,用“E ”表示。
(2)每次运行你所设计的处理器调度程序之前,为每个进程任意确定它的“要求运行时 间”。
(3)把五个进程按顺序排成循环队列,用指针指出队列连接情况。另用一标志单元记录 轮到运行的进程。例如,当前轮到Q 2 执行,则有: 标志单元 k 1k 2k 3 k 4k 5
PCB1 PCB2 PCB3 PCB4 PCB5
(4)处理器调度总是选择标志单元指示的进程运行。由于本实验是模拟处理器调度的功 能,所以,对被选中的进程并不实际启动运行,而是执行: 已运行时间-1
来模拟进程的一次运行,表示进程已经运行过一个单位的时间。
请同学们注意:在实际的系统中,当一个进程被选中运行时,必须置上该进程可以 运行的时间片值,以及恢复进程的现场,让它占有处理器运行,直到出现等待事件 或运行满一个时间片。在这里省去了这些工作,仅用“已运行时间+1”来表示进程 已经运行满一个时间片。
(5)进程运行一次后,应把该进程的进程控制块中的指针值送到标志单元,以指示下一 个轮到运行的进程。同时,应判断该进程的要求运行时间与已运行时间,若该进程 要求运行时间≠已运行时间,则表示它尚未执行结束,应待到下一轮时再运行。若 该进程的要求运行时间=已运行时间,则表示它已经执行结束,应把它的状态修改为 “结束”(E )且退出队列。此时,应把该进程的进程控制块中的指针值送到前面一 个进程的指针位置。
(6)若“就绪”状态的进程队列不为空,则重复上面(4)和(5)的步骤,直到所有进 程都成为“结束”状态。
(7)在所设计的称序中应有显示或打印语句,能显示或打印每次被选中进程的进程名以 及运行一次后进称对列的变化。
(8)为五个进程任意确定一组“要求运行时间”,启动所设计的处理器调度程序,显示或 打印逐次被选中进程的进程名以及进程控制块的动态变化过程。 四、实验报告 (1)实验题目。
(2)程序中使用的数据结构及符号说明。 (3)流程图。
(4)打印一份源程序并附上注释。
(5)打印程序运行时的初值和运行结果,要求如下: i 进程控制块的初始状态
ii. 选中运行的进程名以及选中进程运行后的各进程控制块状态。 对于ii 要求每选中一个进程运行后都要打印。
四、流程图
五、实验代码
#include #include #include #include
using namespace std;
int n; class PCB {
public:
int pri;//进程优先数
int runtime;//进程运行CPU 时间 int pieceOftime;//轮转时间片 string procname;//进程名 string state;//进程状态 int needOftime;//还需要时间 int Counter; PCB * next; };
PCB * run = NULL; PCB * ready = NULL; PCB * finish = NULL; PCB * tial = ready; void Dtime(int t); void Prinft(int a) {
if(a==1) {
cout
cout
void Prinft(int b,PCB * p) {
if(b==1) {
coutprocnameprineedOftimeruntimestate
coutprocnameruntimeneedOftimeCounterpieceOftimestate
void display(int c) {
PCB *p;
if(run!=NULL) /*如果运行指针不空*/
Prinft(c,run); /*输出当前正在运行的PCB*/ //Dtime(2);
p=ready; /*输出就绪队列PCB*/ while(p!=NULL) {
Prinft(c,p); p=p->next; }
//Dtime(2);
p=finish; /*输出完成队列的PCB*/ while(p!=NULL) {
Prinft(c,p); p=p->next; } }
void insert(PCB *p)//插入就绪队列按Pri 大小 {
PCB *S1,*S2; if(ready==NULL) {
p->next = NULL; ready = p; } else {
S1 = ready; S2 = S1;
while(S1!=NULL) {
if(S1->pri >= p->pri) {
S2 = S1;
S1 = S1->next; } else break; }
if(S2->pri >= p->pri) {
S2->next = p; p->next = S1; } else {
p->next = ready;
ready = p; } } }
void queue(PCB *p) {
if(ready==NULL) {
p->next = NULL; ready = p; tial = p; } else {
tial->next = p; tial = p;
p->next = NULL; } }
bool CTProcessOfRuntime() {
PCB * Node; int m;
cout >n;
cout >m;
for(int j = 0;j
Node = new PCB; if(Node==NULL) return false; else {
cout >Node->procname>>Node->needOftime; Node->runtime = 0; Node->state ="就绪"; Node->Counter = 0; Node->pieceOftime = m;
cout procname
queue(Node);
return true; }
void Runtime(int c) {
run = ready;
ready = ready->next; run->state = "运行"; Prinft(c);
while(run!=NULL) {
run->runtime=run->runtime+1;
run->needOftime=run->needOftime-1; run->Counter = run->Counter + 1; if(run->needOftime==0) {
run->state = "完成"; run->next = finish; finish = run; run = NULL; if(ready!=NULL) {
run = ready;
ready = ready->next; } }
else if(run->Counter == run->pieceOftime) {
run->Counter = 0; run->state = "就绪"; queue(run); run=NULL;
if(ready!=NULL) {
run = ready;
run->state = "运行"; ready = ready->next; } }
display(c); } }
int main()
int i;
cout
cout >i; switch(i) {
case 1:
CTProcessOfRuntime(); Runtime(i); break; default: break; }
system ("pause"); return 0; }
void Dtime(int t) {
time_t current_time; time_t start_time; time(&start_time); do {
time(& current_time);
}while((current_time-start_time)
六、程序结果截图
操作系统实验 (第一次)
一、实验内容
选择一个调度算法,实现处理器调度。
二、实验目的
在采用多道程序设计的系统中,往往有若干个进程同时处于就绪状态。当就绪状态进程 个数大于处理器数时,就必须依照某种策略来决定哪些进程优先占用处理器。本实验模拟在 单处理器情况下处理器调度,帮助学生加深了解处理器调度的工作。
三、实验题目
第二题:设计一个按时间片轮转法实现处理器调度的程序。 [提示]
(1)假定系统有五个进程,每一个进程用一个进程控制块PCB 来代表。进程控制块的格 式为: 进程名 时间
要求求运行时间 优先数 状态
其中,进程名----作为进程的标识,假设五个进程的进程名分别是Q 1,Q 2,Q 3,Q 4,Q 5。 指针----进程按顺序排成循环队列,用指针指出下一个进程的进程控制块首地址,最 后一个进程中的指针指出第一个进程的进程控制块首地址。 要求运行时间----假设进程需要运行的单位时间数。
已运行时间----假设进程已经运行的单位时间数,初始值为“0”。
状态----有两种状态,“就绪”状态和“结束“状态,初始状态都为“就绪“,用“R ” 表示,当一个进程运行结束后,它的状态变为“结束”,用“E ”表示。
(2)每次运行你所设计的处理器调度程序之前,为每个进程任意确定它的“要求运行时 间”。
(3)把五个进程按顺序排成循环队列,用指针指出队列连接情况。另用一标志单元记录 轮到运行的进程。例如,当前轮到Q 2 执行,则有: 标志单元 k 1k 2k 3 k 4k 5
PCB1 PCB2 PCB3 PCB4 PCB5
(4)处理器调度总是选择标志单元指示的进程运行。由于本实验是模拟处理器调度的功 能,所以,对被选中的进程并不实际启动运行,而是执行: 已运行时间-1
来模拟进程的一次运行,表示进程已经运行过一个单位的时间。
请同学们注意:在实际的系统中,当一个进程被选中运行时,必须置上该进程可以 运行的时间片值,以及恢复进程的现场,让它占有处理器运行,直到出现等待事件 或运行满一个时间片。在这里省去了这些工作,仅用“已运行时间+1”来表示进程 已经运行满一个时间片。
(5)进程运行一次后,应把该进程的进程控制块中的指针值送到标志单元,以指示下一 个轮到运行的进程。同时,应判断该进程的要求运行时间与已运行时间,若该进程 要求运行时间≠已运行时间,则表示它尚未执行结束,应待到下一轮时再运行。若 该进程的要求运行时间=已运行时间,则表示它已经执行结束,应把它的状态修改为 “结束”(E )且退出队列。此时,应把该进程的进程控制块中的指针值送到前面一 个进程的指针位置。
(6)若“就绪”状态的进程队列不为空,则重复上面(4)和(5)的步骤,直到所有进 程都成为“结束”状态。
(7)在所设计的称序中应有显示或打印语句,能显示或打印每次被选中进程的进程名以 及运行一次后进称对列的变化。
(8)为五个进程任意确定一组“要求运行时间”,启动所设计的处理器调度程序,显示或 打印逐次被选中进程的进程名以及进程控制块的动态变化过程。 四、实验报告 (1)实验题目。
(2)程序中使用的数据结构及符号说明。 (3)流程图。
(4)打印一份源程序并附上注释。
(5)打印程序运行时的初值和运行结果,要求如下: i 进程控制块的初始状态
ii. 选中运行的进程名以及选中进程运行后的各进程控制块状态。 对于ii 要求每选中一个进程运行后都要打印。
四、流程图
五、实验代码
#include #include #include #include
using namespace std;
int n; class PCB {
public:
int pri;//进程优先数
int runtime;//进程运行CPU 时间 int pieceOftime;//轮转时间片 string procname;//进程名 string state;//进程状态 int needOftime;//还需要时间 int Counter; PCB * next; };
PCB * run = NULL; PCB * ready = NULL; PCB * finish = NULL; PCB * tial = ready; void Dtime(int t); void Prinft(int a) {
if(a==1) {
cout
cout
void Prinft(int b,PCB * p) {
if(b==1) {
coutprocnameprineedOftimeruntimestate
coutprocnameruntimeneedOftimeCounterpieceOftimestate
void display(int c) {
PCB *p;
if(run!=NULL) /*如果运行指针不空*/
Prinft(c,run); /*输出当前正在运行的PCB*/ //Dtime(2);
p=ready; /*输出就绪队列PCB*/ while(p!=NULL) {
Prinft(c,p); p=p->next; }
//Dtime(2);
p=finish; /*输出完成队列的PCB*/ while(p!=NULL) {
Prinft(c,p); p=p->next; } }
void insert(PCB *p)//插入就绪队列按Pri 大小 {
PCB *S1,*S2; if(ready==NULL) {
p->next = NULL; ready = p; } else {
S1 = ready; S2 = S1;
while(S1!=NULL) {
if(S1->pri >= p->pri) {
S2 = S1;
S1 = S1->next; } else break; }
if(S2->pri >= p->pri) {
S2->next = p; p->next = S1; } else {
p->next = ready;
ready = p; } } }
void queue(PCB *p) {
if(ready==NULL) {
p->next = NULL; ready = p; tial = p; } else {
tial->next = p; tial = p;
p->next = NULL; } }
bool CTProcessOfRuntime() {
PCB * Node; int m;
cout >n;
cout >m;
for(int j = 0;j
Node = new PCB; if(Node==NULL) return false; else {
cout >Node->procname>>Node->needOftime; Node->runtime = 0; Node->state ="就绪"; Node->Counter = 0; Node->pieceOftime = m;
cout procname
queue(Node);
return true; }
void Runtime(int c) {
run = ready;
ready = ready->next; run->state = "运行"; Prinft(c);
while(run!=NULL) {
run->runtime=run->runtime+1;
run->needOftime=run->needOftime-1; run->Counter = run->Counter + 1; if(run->needOftime==0) {
run->state = "完成"; run->next = finish; finish = run; run = NULL; if(ready!=NULL) {
run = ready;
ready = ready->next; } }
else if(run->Counter == run->pieceOftime) {
run->Counter = 0; run->state = "就绪"; queue(run); run=NULL;
if(ready!=NULL) {
run = ready;
run->state = "运行"; ready = ready->next; } }
display(c); } }
int main()
int i;
cout
cout >i; switch(i) {
case 1:
CTProcessOfRuntime(); Runtime(i); break; default: break; }
system ("pause"); return 0; }
void Dtime(int t) {
time_t current_time; time_t start_time; time(&start_time); do {
time(& current_time);
}while((current_time-start_time)
六、程序结果截图