实验二 进程调度
一.目的和要求
通过这次实验,理解进程调度的过程,进一步掌握进程状态的转变、进程调度的策略,进一步体会多道程序并发执行的特点,并分析具体的调度算法的特点,掌握对系统性能的评价方法。
二.实验内容
阅读教材《计算机操作系统》第二章和第三章,掌握进程管理及调度相关概念和原理。
编写程序模拟实现进程的轮转法调度过程,模拟程序只对PCB进行相应的调度模拟操作,不需要实际程序。假设初始状态为:有n个进程处于就绪状态,有m个进程处于阻塞状态。采用轮转法进程调度算法进行调度(调度过程中,假设处于执行状态的进程不会阻塞),且每过t个时间片系统释放资源,唤醒处于阻塞队列队首的进程。
程序要求如下:
1)输出系统中进程的调度次序;
2)计算CPU利用率。
三.实验环境
Windows操作系统,DevC++
C语言
四.实验报告内容
1.设计思想
(1)程序中进程可用PCB表示,其类型描述如下:
struct PCB_type
{
int pid ; //进程名
int state ; //进程状态
2——表示“执行”状态
1——表示“就绪”状态
0——表示“阻塞”状态
int cpu_time ; //运行需要的CPU时间(需运行的时间片个数)
}
用PCB来模拟进程;
(2)设置两个队列,将处于“就绪”状态的进程PCB挂在队列ready中;将处于“阻塞”状态的进程PCB挂在队列blocked中。 队列类型描述如下:
struct QueueNode{
struct PCB_type PCB;
Struct QueueNode *next;
}
并设全程量:
struct QueueNode *ready_head=NULL,//ready队列队首指针
*ready_tail=NULL , //ready队列队尾指针
*blocked_head=NULL,//blocked队列队首指针
*blocked_tail=NULL; //blocked队列队尾指针
(3)设计子程序:
start_state():读入假设的数据,设置系统初始状态,即初始化就绪队列和阻塞队列。
dispath():模拟调度,当就绪队列的队首进程运行一个时间片后,放到就绪队列末尾,每次都是队首进程进行调度,一个进程运行结束就从就绪队列中删除,当到t个时间片后,唤醒阻塞队列队首进程。
calculate():就绪进程运行一次,usecpu加1,当就绪队列为空时unusecpu加1,CPU利用率为use_cpu/(use_cpu+unuse_cpu)。
实验二 进程调度
一.目的和要求
通过这次实验,理解进程调度的过程,进一步掌握进程状态的转变、进程调度的策略,进一步体会多道程序并发执行的特点,并分析具体的调度算法的特点,掌握对系统性能的评价方法。
二.实验内容
阅读教材《计算机操作系统》第二章和第三章,掌握进程管理及调度相关概念和原理。
编写程序模拟实现进程的轮转法调度过程,模拟程序只对PCB进行相应的调度模拟操作,不需要实际程序。假设初始状态为:有n个进程处于就绪状态,有m个进程处于阻塞状态。采用轮转法进程调度算法进行调度(调度过程中,假设处于执行状态的进程不会阻塞),且每过t个时间片系统释放资源,唤醒处于阻塞队列队首的进程。
程序要求如下:
1)输出系统中进程的调度次序;
2)计算CPU利用率。
三.实验环境
Windows操作系统,DevC++
C语言
四.实验报告内容
1.设计思想
(1)程序中进程可用PCB表示,其类型描述如下:
struct PCB_type
{
int pid ; //进程名
int state ; //进程状态
2——表示“执行”状态
1——表示“就绪”状态
0——表示“阻塞”状态
int cpu_time ; //运行需要的CPU时间(需运行的时间片个数)
}
用PCB来模拟进程;
(2)设置两个队列,将处于“就绪”状态的进程PCB挂在队列ready中;将处于“阻塞”状态的进程PCB挂在队列blocked中。 队列类型描述如下:
struct QueueNode{
struct PCB_type PCB;
Struct QueueNode *next;
}
并设全程量:
struct QueueNode *ready_head=NULL,//ready队列队首指针
*ready_tail=NULL , //ready队列队尾指针
*blocked_head=NULL,//blocked队列队首指针
*blocked_tail=NULL; //blocked队列队尾指针
(3)设计子程序:
start_state():读入假设的数据,设置系统初始状态,即初始化就绪队列和阻塞队列。
dispath():模拟调度,当就绪队列的队首进程运行一个时间片后,放到就绪队列末尾,每次都是队首进程进行调度,一个进程运行结束就从就绪队列中删除,当到t个时间片后,唤醒阻塞队列队首进程。
calculate():就绪进程运行一次,usecpu加1,当就绪队列为空时unusecpu加1,CPU利用率为use_cpu/(use_cpu+unuse_cpu)。
3.程序及注释
#include<stdio.h>
#include<stdlib.h>
struct PCB_type
{
int pid ; //进程名
int state ; //进程状态
//2--表示"执行"状态
//1--表示"就绪"状态
//0--表示"阻塞"状态
int cpu_time ; //运行需要的CPU时间(需运行的时间片个数)
};
struct QueueNode{
struct PCB_type PCB;
struct QueueNode *next;
};
struct QueueNode *ready_head=NULL, //ready队列队首指针
*ready_tail=NULL, //ready队列队尾指针
*block_head=NULL, //blocked队列队首指针
*block_tail=NULL; //blocked队列队尾指针
int use_cpu,unuse_cpu;
void start_state() //读入假设的数据,设置系统初始状态
{
int n,m;
int i;
struct QueueNode *p,*q;
printf("输入就绪节点个数n:");
scanf("%d",&n);
printf("输入阻塞节点个数m:");
scanf("%d",&m);
p=(struct QueueNode *)malloc(sizeof(struct QueueNode));
p->next =NULL;
ready_head=ready_tail=p;
for(i=0;i<n;i++)
{
p=(struct QueueNode *)malloc(sizeof(struct QueueNode));
p->next =NULL;
p->PCB.state=1;
printf("输入就绪进程%d的pid和cpu_time:",i+1);
scanf("%d%d",&p->PCB.pid,&p->PCB.cpu_time);
ready_tail->next=p;
ready_tail=p;
}
q=(struct QueueNode *)malloc(sizeof(struct QueueNode));
q->next =NULL;
block_head=block_tail=q;
for(i=0;i<m;i++)
{
q=(struct QueueNode *)malloc(sizeof(struct QueueNode));
q->next=NULL;
q->PCB.state=0;
printf("输入阻塞进程%d的pid和cpu_time:",i+1);
scanf("%d%d",&q->PCB.pid,&q->PCB.cpu_time);
block_tail->next=q;
block_tail=q;
}
printf("\n处于就绪状态的进程有:\n");
p=ready_head->next;
i=1;
while(p)
{printf("进程%d的pid和state和cpu_time:%5d%5d%5d\n",i,p->PCB.pid,p->PCB.state,p->PCB.cpu_time);
p=p->next;
i++;
}
}
void dispath() //模拟调度
{
int x=0,t;
use_cpu=0;
unuse_cpu=0;
printf("输入t:");
scanf("%d",&t);
printf("开始调度\n");
while(ready_head!=ready_tail||block_head!=block_tail)
{
struct QueueNode *p,*q;
if(ready_head!=ready_tail)
{
p=ready_head->next;
ready_head->next=p->next;
p->next=NULL;
if(ready_head->next==NULL)
{
ready_tail=ready_head;
}
p->PCB.state=2;
printf("进程%d调度\t\n",p->PCB.pid);
use_cpu++;
x++;
p->PCB.cpu_time--;
if(p->PCB.cpu_time)
{
ready_tail->next=p;
ready_tail=p;
}
else
{
printf("进程%d完成\t\n",p->PCB.pid);
free(p);
}
}
else
{
unuse_cpu++;
x++;
printf("空闲一个时间片\t\n");
}
if(x==t&&block_head!=block_tail)
{
q=block_head->next;
block_head->next=q->next;
q->next=NULL;
if(block_head->next==NULL)
{
block_tail=block_head;
}
ready_tail->next=q;
ready_tail=q;
x=0;
}
}
}
void calculate() //计算CPU利用率
{
printf("\ncpu的利用率%.2f\n",(float)use_cpu/(use_cpu+unuse_cpu));
}
int main()
{start_state();
dispath();
calculate();
return 0;
}
4.运行结果:
利用测试用的数据:n=2, m=3, t=5,输出系统中进程的调度次序并
计算出CPU的利用率。