1、实验内容
1)用C语言编程实现对N个进程采用某种进程调度算法(如动态优先权调度算法、先来先服务算法、短进程优先算法、时间片轮转调度算法)调度执行的模拟。
(2)每个用来标识进程的进程控制块PCB可用结构来描述,包括以下字段:
进程标识数ID。
进程优先数PRIORITY,并规定优先数越大的进程,其优先权越高。
进程已占用CPU时间CPUTIME。
进程还需占用的CPU时间ALLTIME。当进程运行完毕时,ALLTIME变为0。
进程的阻塞时间STARTBLOCK,表示当进程再运行STARTBLOCK个时间片后,进程将进入阻塞状态。
进程被阻塞的时间BLOCKTIME,表示已阻塞的进程再等待BLOCKTIME个时间片后,将转换成就绪状态。
进程状态STATE。
队列指针NEXT,用来将PCB排成队列。
(3)优先数改变的原则:
进程在就绪队列中呆一个时间片,优先数增加1。
进程每运行一个时间片,优先数减3。
(4)为了清楚地观察每个进程的调度过程,程序应将每个时间片内的进程的情况显示出来,包括正在运行的进程,处于就绪队列中的进程和处于阻塞队列中的进程。
(5)分析程序运行的结果,谈一下自己的认识。
2、实验结果及分析
1、调度程序的运行实验结果截图

图1

图2

图3
分析:
图1和图2模拟了一个简单的进程调度过程,根据进程的优先级和运行时间来进行调度,直到所有进程运行完成。
具体而言,1、进程控制块(PCB):定义了一个结构体 pcb 用来表示进程控制块,包括进程名、状态、优先级、需要运行时间、已经运行时间等信息。使用了 typedef 将 struct pcb 重命名为 PCB,提高代码可读性。
2、它其中有一个进程优先级排列函数sort(),对进程根据其优先级进行排序,以便按照优先级高低进行调度。使用的是插入排序的思想,根据进程的优先级将其插入到就绪队列中的适当位置。3、然后用户输入需要调度的进程数量以及每个进程的信息,包括进程名、优先级、需要运行时间等。每个进程被创建后,调用 sort() 函数将其按优先级插入到就绪队列中。
4、就绪队列长度计算函数 space():返回当前就绪队列的长度。
5、进程显示函数 disp():用于显示当前进程的信息。
6、进程查看函数 check():显示当前正在运行的进程和就绪队列的状态。
7、进程撤消函数 destroy():进程运行结束后调用,释放进程控制块占用的内存。
8、进程就绪函数 running():进程运行时间到时,将进程状态置为就绪,更新其优先级,并重新排序就绪队列。
9、主函数 main():调用 input() 函数创建进程。循环执行进程调度过程,直到所有进程都运行完成。在每次循环中,从就绪队列中取出一个进程进行运行,调用 check() 函数显示当前状态,然后调用 running() 函数执行进程,并等待用户按键继续。
图3
优先数法
进程就绪队列按优先数大小从高到低排列,链首进程首先投入运行。进程每执行一次,进程需要的时间片数减1、该进程的优先数减3。这样,该进程如果在一个时间片中没有完成,其优先数降低一级。接着仍是用该进程降低一级后的优先数与就绪队列中链首进程的优先数进行比较,如果仍是该进程的优先数高或相同,便让该进程继续执行;否则,调度就绪队列的链首进程投入运行。原运行过的进程按其现行优先数大小插入就绪队列,且改变它们对应的进程状态,一直到所有进程都运行完各自的时间片数。
(3) 时间轮转法
进程就绪队列按各进程进入的先后顺序排列。进程每次所需处理机的轮转式按其重要程度记入进程控制块中的轮转时间片数记录项。进程执行时,每运行一个时间片,进程还需要的时间片数减1,运行进程占用处理机的时间片数加1,然后比较占用CPU的时间片数是否与该进程的轮转时间片数相等,若相等则说明已达到轮转时间,应将现运行的进程排列就绪队列的末尾,调度队列上的首进程运行,且改变它们的进程状态,直至所有进程完成各自的时间片。
————————————————
来自这篇文章
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/g15827636417/article/details/53365903


3、如何在linux下编写并执行c语言程序以及实验源代码
1,使用vim编辑器编写程序,可在终端输入命令:sudo apt-get install vim 下载最新vim

2,需要下载c语言的编译器gcc,在终端输入命令:sudo apt-get install gcc 下载gcc

3,使用vi非常的简单,命令 # vi filename ,即可打开filename的文件,如果filename不存在则会新建一个。这里我们输入命令 :
vi test.c

4,我们进入文件后,这是一般模式,你还不能输入任何字符,键入字符 i,,左下角显示 插入模式,表示我们进入了编辑模式,这时可以直接敲代码了。
敲好源程序后,我们先按 Esc 键退出编辑模式,再输 shift+: 键进入命令行模式,左下角出现 :号,我们输入 wq,表示 保存并退出 ;再按Enter键即可。

我们又来到了终端界面,这时候有了源文件,我们来编译,命令如下:
gcc -o test test.c
成功后,我们查看当前目录下出现一个名为test 的可执行文件,
接着执行,通过命令# ./test 即可执行 !

该部分来源此文章
源代码
代码一
#include "stdio.h"
#include <stdlib.h>
#define getpch(type) (type*)malloc(sizeof(type))
struct pcb { /* 定义进程控制块PCB */
char name[10]; //进程名
char state; //进程状态:"W"-就绪态,"R"-运行态
int nice; //进程优先级
int ntime; //需要运行时间
int rtime; //已经运行的时间
struct pcb* link;
}*ready=NULL,*p;
typedef struct pcb PCB;
char sort() /* 建立对进程进行优先级排列函数,优先数大者优先*/
{
PCB *first, *second;
int insert=0;
if((ready==NULL)||((p->nice)>(ready->nice)))/*优先级最大者,插入队首*/
{
p->link=ready;
ready=p;
}
else /* 进程比较优先级,插入适当的位置中*/
{
first=ready;
second=first->link;
while(second!=NULL)
{
if((p->nice)>(second->nice)) /*若插入进程比当前进程优先数大,*/
{ /*插入到当前进程前面*/
p->link=second;
first->link=p;
second=NULL;
insert=1;
}
else /* 插入进程优先数最低,则插入到队尾*/
{
first=first->link;
second=second->link;
}
}
if(insert==0) first->link=p;
}
}
char input() /* 建立进程控制块函数*/
{
int i,num;
printf("\n 请输入被调度的进程数目:");
scanf("%d",&num);
for(i=0;i<num;i++)
{
printf("\n 进程号No.%d:",i);
p=getpch(PCB);
printf("\n 输入进程名:");
scanf("%s",p->name);
printf(" 输入进程优先数:");
scanf("%d",&p->nice);
printf(" 输入进程运行时间:");
scanf("%d",&p->ntime);
printf("\n");
p->rtime=0;
p->state='W';
p->link=NULL;
sort(); /* 调用sort函数*/
}
}
int space()
{
int l=0; PCB* pr=ready;
while(pr!=NULL)
{
l++;
pr=pr->link;
}
return(l);
}
char disp(PCB * pr) /*建立进程显示函数,用于显示当前进程*/
{
printf("\n qname \t state \t nice \tndtime\truntime \n");
printf("%s\t",pr->name);
printf("%c\t",pr->state);
printf("%d\t",pr->nice);
printf("%d\t",pr->ntime);
printf("%d\t",pr->rtime);
printf("\n");
}
char check() /* 建立进程查看函数 */
{
PCB* pr;
printf("\n **** 当前正在运行的进程是:%s",p->name); /*显示当前运行进程*/
disp(p);
pr=ready;
if (pr!=NULL)
printf("\n ****当前就绪队列状态为:"); /*显示就绪队列状态*/
else
printf("\n ****当前就绪队列状态为: 空\n"); /*显示就绪队列状态为空*/
while(pr!=NULL)
{
disp(pr);
pr=pr->link;
}
}
char destroy() /*建立进程撤消函数(进程运行结束,撤消进程)*/
{
printf(" 进程 [%s] 已完成.\n",p->name);
free(p);
}
char running() /* 建立进程就绪函数(进程运行时间到,置就绪状态*/
{
(p->rtime)++;
if(p->rtime==p->ntime)
destroy(); /* 调用destroy函数*/
else
{
(p->nice)--;
p->state='W';
sort(); /*调用sort函数*/
}
}
int main() /*主函数*/
{
int len,h=0;
char ch;
input();
len=space();
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();
}
printf("\n\n 所有进程已经运行完成!\n");
ch=getchar();
}
代码二:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
typedef struct node{
char name[10];
int prio;
int round;
int cputime;
int needtime;
int count;
char state;
struct node *next;
}PCB;
PCB *finish,*ready,*run,*r;
int N;
void firstin()
{
run = ready;
run->state = 'R';
ready = ready->next;
}
void prt1(char a)
{
if(a=='P'||a == 'p')
printf("进程号 cpu时间 所需时间 优先数 状态\n");
else if(a =='r'||a =='R')
printf("进程号 cpu时间 所需时间 记数 时间片 状态\n");
else if(a=='f'||a=='F')
printf("进程号 所需时间 状态\n");
}
void prt2(char a ,PCB *q)
{
if(a=='P'||a == 'p')
printf("%-10s%-10d%-10d%-10d%c\n",q->name,q->cputime,q->needtime,q->prio,q->state);
else if(a == 'r'|| a == 'R')
printf("%-10s%-10d%-10d%-10d%-10d%c\n",q->name,q->cputime,q->needtime,q->count,q->round,q->state);
else if(a=='f'||a=='F')
printf("%-10s%-10d%c\n",q->name,q->needtime,q->state);
}
void prt(char algo)
{
PCB *p;
prt1(algo);
if(run != NULL&& !(algo == 'r'||algo =='R'))//这个对RR不适应!!
prt2(algo,run);
p = ready;
while(p != NULL)
{
prt2(algo,p);
p = p->next;
}
p = finish;
while(p != NULL)
{
prt2(algo,p);
p = p->next;
}
getchar();
}
void insert1(PCB *q)
{
PCB *p1,*s,*r;
int b;
s = q;
p1 = ready;
r = p1;
b = 1;
while((p1 != NULL)&&b)
{
if(p1->prio >= s->prio)
{
r = p1;
p1 = p1->next;
}
else b = 0;
}
if(r!= p1)
{
r->next = s;
s->next = p1;
}
else
{
s->next = p1;
ready = s;
}
}
void creat1(char alg)
{
PCB *p;
int i,time;
char na[10];
ready = NULL;
finish = NULL;
run = NULL;
printf("输入进程号和运行时间:\n");
for(i = 1; i <= N; i++)
{
p = (PCB *)malloc(sizeof(PCB));
scanf("%s",na);
scanf("%d",&time);
strcpy(p->name,na);
p->cputime = 0;
p->needtime = time;
p->state = 'W';
p->prio = 50-time;
if(ready != NULL)
insert1(p);
else{
p->next = ready;
ready = p;
}
}
//clrscr();
if(alg =='p'||alg =='P')
printf(" 优先数算法输出信息:\n");
else
printf(" 先来先服务算法输出信息:\n");
printf("*****************************************\n");
prt(alg);
run = ready;
ready = ready->next;
run->state = 'R';
}
void creat2(char alg)
{
PCB *p;
int i,time,round;
char na[10];
ready = NULL;
finish = NULL;
run = NULL;
printf("请输入时间片:");
scanf("%d",&round);
printf("输入进程号和运行时间:\n");
for(i = 1; i <= N; i++)
{
p = (PCB *)malloc(sizeof(PCB));
scanf("%s",na);
scanf("%d",&time);
strcpy(p->name,na);
p->cputime = 0;
p->needtime = time;
p->state = 'W';
p->count = 0;
p->round = round;
p->next = NULL;
if(i == 1)/*按顺序插入到ready链表中*/
r = ready = p;
else
r->next = p;
r = p;
}
//clrscr();
printf(" 时间片轮转算法输出信息:\n");
printf("*****************************************\n");
prt(alg);
}
void priority(char alg) //优先数调度算法
{
while(run != NULL)
{
run->cputime += 1;
run->needtime -= 1;
run->prio -= 3;
if(run->needtime == 0)
{
run->next = finish;
finish = run;
run->state = 'F';
run = NULL;
if(ready != NULL)
firstin();
}
else
if((ready != NULL) && (run->prio < ready->prio))
{
run->state = 'W';
insert1(run);
firstin();
}
prt(alg);
}
}
void roundrun(char alg) //时间片轮转调度算法
{
bool flag;//当ready列里只有一个时做标记
while(N){
flag = 1;//初始化为1
run = ready;//run每次运行ready的队头
run->count++;//每运行一次计数器加1
if(run->needtime < run->round)//当剩余时间小于时间片轮转时间时的情况
{
run->cputime += run->needtime;
run->needtime = 0;
}
else{
run->cputime += run->round;
run->needtime -= run->round;
}
run->state = 'W';//变为等待
if(ready->next != NULL)
ready = ready->next;
else flag = 0;//当ready剩一个时做标记
if(run->needtime == 0){//当run结束时放入finish队列里
run->next = finish;
finish = run;
run->state = 'F';
N--;//进程数少1
}
else{
if(flag){//执行完如果不是剩一个的话,就把run放到队尾
r->next = run;
r = run;
r->next = NULL;
}
}
if(N)ready->state = 'R';//结束时不应该有'R"
else
ready = NULL;//结束时应该为空
prt(alg);//输出
}
}
void FCFSrun(char alg) //先来先服务调度算法
{
PCB *p;
while(run!=NULL)
{
run->cputime += run->needtime;
run->needtime =0;
run->next = finish;
finish = run;
run->state = 'F';
run = NULL;
if(ready!=NULL)
firstin();
prt(alg);
}
}
int main()
{
char algo;
//clrscr();
printf("选择算法:P/R/F(优先数算法/时间片轮转算法/先来先服务算法)\n");
scanf("%c",&algo);
printf("输入进程数:\n");
scanf("%d",&N);
if(algo == 'P'||algo == 'p')
{
creat1(algo);
priority(algo);
}
else if(algo == 'R'||algo == 'r')
{
creat2(algo);
roundrun(algo);
}
else if(algo=='f'||algo=='F')
{
creat1(algo);
FCFSrun(algo);
}
system("echo 按任意键退出");
system("read -n 1");
return 0;
}

2479

被折叠的 条评论
为什么被折叠?



