赞
踩
#include <stdio.h>
#include <stdlib.h>
#include<dos.h>
#include<time.h>
#include<conio.h>
#include<string.h>
#define INF 1000000.0
typedef char string[10];
struct task
{
int ID; //进程号
string name; //进程名
int arrivetime; //到达时间
int servicetime; //服务时间
int waittime; //等待时间
int starttime; //开始运行时间
int finishtime; //结束运行时间
float turnaroundtime; //周转时间
float weightedturnaroundtime; //带权周转时间
int priority; //优先权
int finish; //是否已经完成
}PCB[10];
struct PCB {
char id[10]; // 进程ID
double reachTime; // 进程到达的时间
double needTime; // 进程完成需要的时间
double startTime; // 进程开始的时刻
double finishTime; // 进程完成的时刻
double cTime; // 进程周转时间
double wcTime; // 进程带权周转时间
char state; // 进程的状态( 设每个进程处于就绪R(ready),完成F(finish)两种状态之一 )
};
int num;
void input()
{
int i;
printf("\n请输入作业数量:");
scanf("%d",&num);
for(i=0;i<num;i++)
{
printf("\n请输入进程%d:\n",i);
printf("进程名 到达时间 服务时间\n");
scanf("%s%9d%9d",PCB[i].name,&PCB[i].arrivetime,&PCB[i].servicetime);
PCB[i].priority=0;
PCB[i].finish=0;
}
}
int HRN(int pre)
{
int current=1,i,j; //优先权=(等待时间+要求服务时间)/要求服务时间
for(i=0;i<num;i++)
{
PCB[i].waittime=PCB[i].finishtime-PCB[i].arrivetime; //等待时间=上一个进程的完成时间-到达时间
PCB[i].priority=(PCB[i].waittime+PCB[i].servicetime)/PCB[i].servicetime;
}
for(i=0;i<num;i++)
{
if(!PCB[i].finish)
{
current=i; //找到第一个还没完成的作业
break;
}
}
for(j=i;j<num;j++) //和后面的作业比较
{
if(!PCB[i].finish) //还没完成(运行)
{
if(PCB[current].arrivetime<=PCB[pre].finishtime) //如果进程在上一个进程完成之前到达
{
if(PCB[j].arrivetime<=PCB[pre].finishtime && PCB[j].priority>PCB[current].priority)
current=j; //找出到达时间在上一个进程完成之前,优先权高的进程
}
else //如果进程是在上一个进程完成之后到达
{
if(PCB[j].arrivetime<PCB[current].arrivetime)
current=j; //找出比较早到达的一个
if(PCB[j].arrivetime==PCB[current].arrivetime) //如果同时到达
if(PCB[j].priority>PCB[current].priority)
current=j; //找出服务时间比较短的一个
}
}
}
return current; //返回当前进程
}
void running(int i,int times,int pre,int statime,int endtime)
{
if(times==0)
{
PCB[i].starttime=PCB[i].arrivetime;
PCB[i].finishtime=PCB[i].starttime+PCB[i].servicetime;
PCB[i].turnaroundtime=PCB[i].servicetime;
PCB[i].weightedturnaroundtime=1.0;
statime=PCB[i].starttime;
}
else
{
if(PCB[i].arrivetime>PCB[pre].finishtime)
PCB[i].starttime=PCB[i].arrivetime;
else
PCB[i].starttime=PCB[pre].finishtime;
PCB[i].finishtime=PCB[i].starttime+PCB[i].servicetime;
PCB[i].turnaroundtime=PCB[i].finishtime-PCB[i].arrivetime;
PCB[i].weightedturnaroundtime=PCB[i].turnaroundtime/PCB[i].servicetime;
}
if(times==num-1)
endtime=PCB[i].finishtime;
PCB[i].finish=1;
}
void print(int i,int times)
{
if(times==0)
{
printf("ID 进程名 到达时间 服务时间 开始时间 完成时间 周转时间 带权周转时间\n");
}
printf("%d%9s%9d%9d%9d%9d%10.1f%10.2f\n",PCB[i].ID,PCB[i].name,PCB[i].arrivetime,PCB[i].servicetime,
PCB[i].starttime,PCB[i].finishtime,PCB[i].turnaroundtime,PCB[i].weightedturnaroundtime);
}
void check()
{
int i;
int statime,endtime,sumturtime=0.00,sumwtutime=0.00;
int current=0,times=0,pre=0;
float aveturtime,avewtutime;
PCB[pre].finishtime=0;
for(i=0;i<num;i++)
{
PCB[i].finish=0;
}
statime,endtime,sumturtime=0.00,sumwtutime=0.00,aveturtime,avewtutime;
current=0;times=0;pre=0;
PCB[pre].finishtime=0;
printf("\n");
for(i=0;i<num;i++)
{
PCB[i].finish=0;
}
statime,endtime,sumturtime=0.00,aveturtime,avewtutime;
current=0;times=0;pre=0;
PCB[pre].finishtime=0;
printf("\n");
for(times=0;times<num;times++)
{
current=HRN(pre);
running(current,times,pre,statime,endtime);
print(current,times);
pre=current;
}
float sum=0;
for(i=0;i<num;i++)
{
sumturtime+=PCB[i].turnaroundtime;
sum=sum+PCB[i].weightedturnaroundtime;
}
aveturtime=sumturtime/num;
avewtutime=sum/num;
printf("(平均带权周转时间) %.3lf\n",avewtutime);
printf("\n");
}
void hrrn()
{
input();
check();
}
/* 两种情况:
1.在lastTime时刻,选择已经到达且拥有最短运行时间的进程
2.在lastTime时刻,没有进程到达,此时选择拥有最早到达时间的进程
*/
int findNext( struct PCB arr[], int length, double lastTime ) {
// p是已经到达且拥有最短运行时间的进程的下标
// q是没有到达的进程中拥有最早到达时间的进程的下标
int i, p, q;
double minNeedTime, minReachTime,minTime;
minTime= 1000000;
p = q = -1; minNeedTime = minReachTime = INF;
for( i = 0; i < length; i++ ) {
if( arr[i].state=='R' ) { // 进程处就绪状态
// 第一情况
if( arr[i].reachTime<=lastTime && arr[i].needTime<minNeedTime )
{ p = i; minNeedTime = arr[i].needTime; }
// 第二种情况
if( arr[i].reachTime>lastTime && arr[i].reachTime<=minReachTime ){
if(arr[i].needTime<minTime)
{ q = i; minReachTime = arr[i].reachTime; minTime = arr[i].needTime; }
}}
}
// p为-1时,代表在lastTime时刻还没进程到达,此时选择下一个最早到达的进程q
printf("%d------------",q);
if( p != -1 ) return p;
return q;
}
int sjf(){
int num, i;
double lastTime; // 为上一个进程的完成时间,用来确定当前进程的开始时间
struct PCB *arr;
printf( "请输入进程数:" );
scanf( "%d", &num );
arr = (struct PCB*)malloc(num*sizeof(struct PCB));
lastTime = INF; // 最开始lastTime的为第一个作业的reachTime(到达时间)
printf( "请依次输入进程ID,进程到达时间,进程运行时间:\n" );
for( i = 0; i < num; i++ ) {
scanf( "%s%lf%lf", arr[i].id, &arr[i].reachTime, &arr[i].needTime );
arr[i].state = 'R';
if( lastTime>arr[i].reachTime ) lastTime = arr[i].reachTime;
}
// sum1为所有进程周转时间之和,sum2为所有进程带权周转时间之和
double sum1=0.0, sum2=0.0;
for( i = 0; i < num; i++ ) {
int p = findNext( arr, num, lastTime ); // 找到下一个将要执行的进程
// 两种情况:将要执行的进程可能已经到达,或者还没到达
if( arr[p].reachTime<=lastTime ) arr[p].startTime = lastTime;
else arr[p].startTime = arr[p].reachTime;
// 确定进程的完成时间,周转时间,带权周转时间
arr[p].finishTime = arr[p].startTime + arr[p].needTime;
arr[p].cTime = arr[p].finishTime - arr[p].reachTime;
arr[p].wcTime = arr[p].cTime/arr[p].needTime;
arr[p].state = 'F';
sum1 += arr[p].cTime;
sum2 += arr[p].wcTime;
lastTime = arr[p].finishTime; // 更新lastTime
}
printf( "\n进程 到达时间 运行时间 开始时间 完成时间 周转时间 带权周转时间\n" );
for( i = 0; i < num; i++ ) {
printf( "%4s %8.2lf %8.2lf ", arr[i].id, arr[i].reachTime, arr[i].needTime );
printf( "%8.2lf %8.2lf ", arr[i].startTime, arr[i].finishTime );
printf( "%8.2lf %12.2lf\n", arr[i].cTime, arr[i].wcTime );
}
printf( "平均周转时间: %.3lf\n", sum1/num );
printf( "平均带权周转时间: %.3lf\n", sum2/num );
return 0;
}
int cmp( const void *a, const void *b ) {
if( ((struct PCB*)a)->reachTime < ((struct PCB*)b)->reachTime ) return -1;
return 1;
}
int fcfs(){
int num, i;
double lastTime; // 为上一个进程的完成时间,用来确定当前进程的开始时间
struct PCB *arr;
printf( "请输入进程数:" );
scanf( "%d", &num );
arr = (struct PCB*)malloc(num*sizeof(struct PCB));
lastTime = INF; // 最开始lastTime的为第一个作业的reachTime(到达时间)
printf( "请依次输入进程ID,进程到达时间,进程运行时间:\n" );
for( i = 0; i < num; i++ ) {
scanf( "%s%lf%lf", arr[i].id, &arr[i].reachTime, &arr[i].needTime );
arr[i].state = 'R';
if( lastTime>arr[i].reachTime ) lastTime = arr[i].reachTime;
}
qsort( arr, num, sizeof(struct PCB), cmp ); // 将进程按reachTime(到达时间)进行排序
// sum1为所有进程周转时间之和,sum2为所有进程带权周转时间之和
double sum1=0.0, sum2=0.0;
for( i = 0; i < num; i++ ) {
int p = i; // 找到下一个将要执行的进程
// 两种情况:将要执行的进程可能已经到达,或者还没到达
if( arr[p].reachTime<=lastTime ) arr[p].startTime = lastTime;
else arr[p].startTime = arr[p].reachTime;
// 确定进程的完成时间,周转时间,带权周转时间
arr[p].finishTime = arr[p].startTime + arr[p].needTime;
arr[p].cTime = arr[p].finishTime - arr[p].reachTime;
arr[p].wcTime = arr[p].cTime/arr[p].needTime;
arr[p].state = 'F';
sum1 += arr[p].cTime;
sum2 += arr[p].wcTime;
lastTime = arr[p].finishTime; // 更新lastTime
}
printf( "\n进程 到达时间 运行时间 开始时间 完成时间 周转时间 带权周转时间\n" );
for( i = 0; i < num; i++ ) {
printf( "%4s %8.2lf %8.2lf ", arr[i].id, arr[i].reachTime, arr[i].needTime );
printf( "%8.2lf %8.2lf ", arr[i].startTime, arr[i].finishTime );
printf( "%8.2lf %12.2lf\n", arr[i].cTime, arr[i].wcTime );
}
printf( "平均周转时间: %.3lf\n", sum1/num );
printf( "平均带权周转时间: %.3lf\n", sum2/num );
return 0;
}
void main(){
for(int i=0;i<3;i++){
printf("\n-------------算法选择--------------\n");
printf("\n1.短作业优先算法\n");
printf("\n2.先来先服务算法\n");
printf("\n3.高响应比优先调度算法算法\n");
int a=0;
printf("\n请选择序号:\n");
a=0;
scanf("\n%d",&a);
switch(a){
case 1:{ printf("\n-------------短作业优先算法--------------\n");
sjf();break;}
case 2:{ printf("\n-------------先来先服务算法--------------\n");
fcfs();
break;}
case 3:{
printf("\n-------------高响应比优先调度算法算法--------------\n");
hrrn();break;}
}}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。