i快鬲紳狡犬爹
整芦 SHAANXI UNIVERSITY OF SCIENCE & TECHNOLOG¥
操作系统实验报告
实验1 进程调度算法
报告日期:2016-6-10
姓 名:
学 号:
班 级: 任课教师:
实验1 进程调度算法
一、 实验内容
按优先数调度算法实现处理器调度。
二、 实验目的在采用多道程序设计的系统中, 往往有若干个进程同时处于就绪状态。
当就绪进程个数 大于处理器数时,就必须依照某种策略来决定哪些进程优先占用处理器。 本实验模拟在单处
理器情况下的处理器调度,帮助学生加深了解处理器调度的工作。
三、 实验原理
设计一个按优先数调度算法实现处理器调度的程序。
假定系统有五个进程,每一个进程用一个进程控制块 PCB来代表,进程控制块的格式为:
进程名
指针
要求运行时间
优先数
状态
其中,进程名一一作为进程的标识,假设五个进程的进程名分别为 Pi,P2, P3, P4, P5。
指针一一按优先数的大小把五个进程连成队列, 用指针指出下一个进程的进程控制块的首地址,最后一个进程中的指针为“ 0”
要求运行时间一一假设进程需要运行的单位时间数。
优先数一一赋予进程的优先数,调度时总是选取优先数大的进程先执行。
状态——可假设有两种状态, “就绪”状态和“结束”状态。五个进程的初始状态都为
“就绪”,用“ R”表示,当一个进程运行结束后,它的状态为“结束” ,用“ E”表示。
在每次运行你所设计的处理器调度程序之前,为每个进程任意确定它的“优先数” 和“要求运行时间”。
为了调度方便,把五个进程按给定的优先数从大到小连成队列。用一单元指出队首 进程,用指针指出队列的连接情况。例:
队首标志
K2
Ki
Pi
K2
P2
K3
P3
K4
P4
K5
P5
0
K4
K5
K3
K1
2
3
1
2
4
1
5
3
4
2
R
R
R
R
R
PCB1
PCB2
PCB3
PCB4
PCB5
处理器调度总是选队首进程运行。采用动态改变优先数的办法,进程每运行一次优 先数就减“1”。由于本实验是模拟处理器调度, 所以,对被选中的进程并不实际的启动运行, 而是执行:
优先数-1
要求运行时间-1
来模拟进程的一次运行。
提醒注意的是:在实际的系统中, 当一个进程被选中运行时,必须恢复进程的现场, 让
它占有处理器运行,直到出现等待事件或运行结束。在这里省去了这些工作。
进程运行一次后,若要求运行时间 -0,则再将它加入队列(按优先数大小插入,且
置队首标志);若要求运行时间=0,则把它的状态修改成“结束” (E),且退出队列。
若“就绪”状态的进程队列不为空,则重复上面( 4)和(5)的步骤,直到所有进
程都成为“结束”状态。
在所设计的程序中应有显示或打印语句, 能显示或打印每次被选中进程的进程名以
及运行一次后进程队列的变化。
为五个进程任意确定一组“优先数”和“要求运行时间” ,启动所设计的处理器调
度程序,显示或打印逐次被选中进程的进程名以及进程控制块的动态变化过程。
四、实验内容
画出算法流程图
建立PCB 结构体
建立PCB 结构体J
输出每一;欠 运行结果?
初始化进
程冲 r
' 在谁表中刪
除该结加
按照优先数
大小构建一 3
个有序舖表」
模拟进程 运行心要求运行时
模拟进程 运行心
要求运行时
、 间是否为0*
程序中使用的数据结构及符号说明。
1>结构体
typedef struct PCB //圭寸装进程结构体
{
char n ame[2];
int time;
int prior_num;
char state;
struct PCB" next;
}PCEJ* pPCB //结构体名为PCB pPCB是指向结构体的指针
2>链表
pPCBCreateLink( PCB" arr )
{
int i = 0;
int j = 0;
int pos = 0;
int posl = 0;
pPCBiead = NULL
for (i = 0; i < N; i++) //先找出优先级最高的进程,赋给
头结点
if ( arr [i].prior_num == N)
}
}
}
}
}
}
{
pos = i;
break;
}
}
head = & arr [pos];
for (i = N - 1; i > 0; i--) //按优先级大小依次找到其他
进程,链起来
{
for (j = 0; j < N j++)
{
if ( arr [j].prior_num == i)
{
pos1 = j;
break;
}
}
arr [pos].next = & arr [pos1];
pos = pos1;
}
return head;//
return head;
//返回头结点
3.源程序
#defi ne _CRT_SECURE_NO_WARNINGS #ifndef _SCHEDULING_H_
#defi ne _SCHEDULIHG_H__ #defi ne N5
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
typedef struct PCB //圭寸装进程结构体
{ |
char n ame[2];
int time;
int prior_num;
char state;
struct PCB* next;
}PCB * pPCB //结构体名为PCB pPC是指向结构体的指针
pPCBCreateLink( PCharr); //创建链表把5个进程链起来
void InitPCB( PCB*arr, int *a); // 初始化进程
pPCBrunPCB(PCB*arr, pPCBpcb); // 进程运行
void printPCB( PCB^arr); //输出进程的初始状态
void random( int a[], int n); //将数组内容打乱顺序
void PrintRun( pPCEhead); // 输出运行后的进程
#en dif
#include "head.h" void random( int a[], int n)
{
int index, tmp, i;
srand(( unsigned int )time( NULL); for (i = 0; i < n; i++)
{
in dex = ran d() % ( n - i) + i;
if (index != i)
{
tmp = a[i]; a[i] = a[i ndex];
a[i ndex] = tmp;
}
}
pPCBCreateLink( PCB* arr)
{
int i = 0;
int j = 0;
int pos = 0;
int posl = 0;
pPCBhead = NULL
for (i = 0; i < N; i++) //先找出优先级最高的进程,赋给头结点
{
if ( arr [i].prior_num == N
{ _
pos = i;
break;
}
}
head = & arr [pos];
for (i = N - 1; i > 0; i--) //按优先级大小依次找到其他进程,链
起来
{
for (j = 0; j < N; j++)
{
if ( arr [j].prior_num == i)
{ _
pos1 = j; break;
}
}
arr [pos].next = & arr [pos1];
pos = pos1;
}
return head; //返回头结点
}
void InitPCB( PCB* arr , int * a)
{
int i = 0;
char *str[] = { "p1" , "p2" , "p3" , "p4" , "p5" };
for (i = 0; i < N; i++) //将5个进程初始化
{
strcpy( arr [i].name, str[i]);
arr [i].prior_num = a[i];
arr [i].state = 'R';
//
//这里将所需运行时间控制在4以
arr [i].next = NULL
arr [i].time = (rand() % 4) + 1;
内
void printPCB( PCh arr) //打印进程最初状态
{
int i = 0;
for (i = 0; i < N; i++)
{
printf("进程名称:%s\n", arr [i].name);
printf("进程优先级:%d\n", arr [i].prior_num); printf("进程所需运行时间:%d\n", arr [i].time); printf("进程当前状态:%c\n", arr [i].state); printf( "\n");
pPCBrunPCB(pPCBhead, pPCBpcb) // 进程执行函数
{
int i = 0;
pPCB:ur= head;
pPCEprev = NULL;
while (cur)
{
cur->time--; //先让进程的时间和优先级减一
cur->prior_ nu m--;
if (cur->time == 0) //判断所需运行时间是否为0
{
if (cur == head) //判断是否是头结点
{
cur->state =
cur->state = 'E';
head = head- >n ext;
prev->n ext = cur->n ext; cur = cur- >n ext;
}
else //若时间不为0,指针向后移动
{
prev = cur; cur = cur->n ext;
}
}
retur n head;
}
void PrintRun( pPCBhead)
{ | —
pPCB^ur = head;
printf("进程运行:\n");
while (cur)
{
printf("进程名称:%s\n", cur-> name); printf("进程优先级:%d\n", cur->prior_num); printf("所需运行时间:%d\n", cur->time); printf("当前状态:%c\n", cur->state); printf( "\n");
cur = cur->n ext;
}
}
#include "head.h"
int main()
{
PCBpcb;
pPCEhead;
int a[] = { 1,2, 3, 4, 5 };
random(a, N);
PCBarr[ N;
In itPCB(arr,a);
prin tPCB(arr);
head = CreateL in k(arr); printf("运行一次:\n");
head = run PCB(head, & pcb);
Prin tRu n(head); printf("运行二次:\n"); head = run PCB(head, & pcb);
Prin tRu n(head); printf("运行三次:\n"); head = run PCB(head, & pcb);
运行一次:
运行一次:
运行一次:
运行一次:
Prin tRu n(head); getchar(); return 0;
} |
4.程序运行时的初值和运行结果
初始状态:
i井
:1
E:\学习爆作系统实验\优先数调度\DEbug\优先数调度
4 B !
当 口王口王L王口王
2 ? 寸
1 ! P5行太空 级运状 称先需前二 口王口王口王口王 *LhLckrMthL*Lkr- 丄卞-4-J?.4
4
?■
进进进进
间R P4;行态 ■级运状
称先畫刖
当 H
3
■?
间R 5比= P3:行态 级运状
称先遷刖 当 口王口王口王口王 ZCA工A采 进进进进
进
间R
寸
3 B : P2行态 ■?级运状 称先蛊刖 当 il 进进进进
运行三次:
运行三次:
运行三次:
运行三次:
E:\学习僚作乐统实验\优先数调?\Debug\tt^?S.exe
P3■间 R ……级时; 一运绝运忧 -丁呈呈呈:‘
运进进进所当
3
2 :
P2■间 R
称先行态
鲁运状
SS刖
进进所当
3
1-:
厂可
「「
■■纟*!
+-级时: 称先行态 豆运状 8&刖 进进所当
1
P5间 R :级时: 称先行态 绝运状 程程壬丙前 进进肿当
运行两次:
■ E:\学习僚作系统实验\优先数调度\口曲旳\优先数调度.已“
13 :
1
3 :
P3?■间 R ……级时: 二运更剰 ^sis 刖 运进进进所当
P2?■间 R :级时: 称先行态 ?B 进进祈当
妙:程名称;p4 魅前诜级:0 所蛊运行時间宀 当箭状态;R
:nn
诅爲先行态 二运角运状 亍呈黑呈丰fi刖
运进选选所当
:级时: 称先行态 耳运状 i?刖 进选加当
实验小结
五、
在 用程序模拟实现进程的优先数调度过程中, 我对操作系统的进程调度 理解也越来越深刻,不断的调试 BUG让我很有成就感,同时,这个 实验花费了我大量时间让我觉得我还需要有进一步的提升。