操作系统实验—进程调度(轮转法)源码实列

  • Post author:
  • Post category:其他

实验内容

设计一个有 N个进程并发执行的进程调度程序
编写并调试一个模拟的进程调度程序,采用“轮转法”调度算法对五个进程进行调度。

轮转法原理
轮转法可以是简单轮转法、可变时间片轮转法,或多队列轮转法。
简单轮转法的基本思想是:所有就绪进程按 FCFS排成一个队列,总是把处理机分配给队首的进程,各进程占用CPU的时间片相同。如果当前进程用完它的时间片后还未运行完成,就把它送回到就绪队列的末尾,把处理机重新分配给队首的进程。直至所有的进程运行完毕。

实验分析

FCFS:先来先服务调度算法,就是说那个进程先被调入到内存,就先分配资源给它,先执行这个进程。这个算法对长作业是有利的,但是对于短作业是不利的(就类比于去超市买东西,你就买一瓶水,但是要排很长的对),所以平均周转时间较长。

这里使用轮转法的基本思想就是:当你调入了几个进程到内存中来,他们都排成一个队列,我们均匀的给他们分配资源,但是在这里设置一个时间片。当时间片用完以后,该进程能完成执行,则进程执行完毕。如果时间片用完以后进程仍未执行完,就停止对该进程分配资源,并将该进程调入到就绪态队列的末尾。等待下一轮的分配。直到分配的次数够,分配的资源足够进程才能执行完。

源码实列

下面展示一些 内联代码片

在代码中实实现这一轮转法,我们需要运用数据结构中的链表,
通过链表来实现这一轮转。
周转时间=等待时间+处理时间
平均周转时间:各进程周转时间之和/进程数

在这里插入图片描述

代码

#include "stdio.h" 
#include <stdlib.h>
#include <conio.h>
#define getpch(type) (type*)malloc(sizeof(type)) 
#define NULL 0 
struct pcb { /* 定义进程控制块PCB */ 
	char name[10]; //进程名
	char state; //进程状态
	int ntime; //进程需要处理的时间
	int rtime; //已经处理的时间
	int ztime;//周转时间
	struct pcb* link; //将进程用链表的方式存放
}*ready=NULL,*p,*last;//声明头节点,和尾节点
int sum=0; //用于求周转时间的和
typedef struct pcb PCB;//声明结构体变量
void jump(){//跳转方法,如果时间片用完没有执行完进程,就放到就绪队列的最后 
	if(ready==NULL){//如果就绪队列为空 
		ready=p;
	    last=p;
	}
	else{           //就绪队列不为空时,把未执行完的进程放到队列最后 
		last->link=p;
		last=p;
	}
}
void  input() /* 建立进程控制块函数*/ 
{ 
	int i;
	int num; 
//	clrscr(); /*清屏*/ 
	printf("\n 请输入进程个数:"); 
	scanf("%d",&num); 
	for(i=0;i<num;i++) 
	{ 
		printf("\n 进程号No.%d:\n",i); 
		p=getpch(PCB); 
		printf("\n 输入进程名:"); 
    	scanf("%s",p->name);  
		printf("\n 输入进程运行时间:"); 
		scanf("%d",&p->ntime); 
		printf("\n"); 
		p->rtime=0;
		p->ztime=0;
		p->state='w'; 
		p->link=NULL; 
		jump(); //调用jump函数 
	 } 
} 
int space() //队列中进程的数目(链表的长度) 
{ 
	int l=0; PCB* pr=ready; //(pr为一个用于遍历的指针) 
	while(pr!=NULL) 
	{ 
		l++; 
		pr=pr->link; 
	 } 
	return(l); 
} 
void disp(PCB * pr) /*建立进程显示函数,用于显示当前进程*/ 
{ 
	printf("\n qname \t state \t ntime \t rdtime \t ztime \n"); 
	printf("|%s\t",pr->name); 
	printf("|%c\t",pr->state);  
	printf("|%d\t",pr->ntime); 
	printf("|%d\t",pr->rtime); 
	printf("|%d\t",pr->ztime);
	printf("\n"); 
} 
void check() /* 建立进程查看函数 */ 
{ 
	PCB* pr; 
	printf("\n **** 当前正在运行的进程是:%s",p->name); /*显示当前运行进程*/ 
	disp(p); 
	pr=ready; 
	printf("\n  ****当前就绪队列状态为:\n"); /*显示就绪队列状态*/ 
	while(pr!=NULL) 
	 { 
	   	(pr->ztime)++;
		disp(pr); 
		pr=pr->link; 
	 } 
} 
void destroy() /*建立进程撤消函数(进程运行结束,撤消进程)*/ 
{ 
	printf("\n 进程 [%s] 已完成.\n",p->name); 
	sum=sum+p->ztime;
	free(p); 
	
} 
void  running() /* 建立进程就绪函数(进程运行时间到,置就绪状态*/ 
{   
	(p->rtime)++;
	 (p->ztime)++; 
	if(p->rtime==p->ntime){
		destroy(); /* 调用destroy函数*/ 
	} 
	else
	 { 
		p->state='w'; 
		jump(); /*调用jump函数*/ 
	 } 
} 
int  main() /*主函数*/ 
{ 
	int len,h=0;
	float x; 
	char ch; 
	input(); 
	len=space(); 
	
/*	PCB *pr = ready;
	while( pr!=NULL ) {
		printf("ok ");
		pr = pr->link;
	}*/
	
	while((len!=0)&&(ready!=NULL)) 
	{ 
		ch=getchar(); 
		h++; 
		printf("\n The execute number:%d \n",h); 
		p=ready; 
		ready=p->link; 
		p->link=NULL; 
		p->state='R'; 
	    check(); 
		running(); 
		printf("\n 按任一键继续......"); 
		ch=getchar(); 
	} 
	
	x=(float)sum/len;
	printf("平均周转时间:%.2f",x);
	printf("\n\n 进程已经完成.\n"); 
	ch=getchar(); 
}


有帮助的话,点个赞哦(^ _ ^)

Thanks!


版权声明:本文为m0_56145255原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。