一、 实验目的
在采用多道程序设计的系统中,有若干个进程同时处于就绪状态。当就绪进程个数大于处理机数时,就必须依照某种调度策略决定哪些进程可以分到处理机,本实验模拟在单处理机情况下的处理机调度。
二、实验内容
1、 设计一个进程控制块PCB
包括:进程名、进程优先数、进程所占CPU时间、还需要CPU时间、进程状态、下一列指针
2、建立进程就绪队列:要求按照不同调度算法建立就绪队列
3、 编制两个调度算法,进程数由用户从键盘输入 (1)时间片轮转法(时间片为2) (2)优先数算法
初始优先数 = 50 - 运行时间
每运行一次优先数减3,时间片为2。
4、运行结果 (提示:name为进程名; cputime 为CPU已运行的时间单位数; needtime 为进程还需要运行的时间单位数;
count为已经运行的轮数;round为被分配的时间片数量; state中R代表运行,W代表等待。)
一、 时间片轮转法(带下划线表示输入)
输入:
input name and needtime:
a1 3
a2 2
a3 4
a4 2
a5 1
显示结果:
Name cputime needtime count round state
a1 0 3 0 2 R
a2 0 2 0 2 W
a3 0 4 0 2 W
a4 0 2 0 2 W
a5 0 1 0 2 W
就绪队列:a2、a3、a4、a5
完成队列:
Name cputime needtime count round state
a2 0 2 0 2 R
a3 0 4 0 2 W
a4 0 2 0 2 W
a5 0 1 0 2 W
a1 2 1 1 2 W
就绪队列:a3、a4、a5 、a1
完成队列:
Name cputime needtime count round state
a3 0 3 0 2 R
a4 0 2 0 2 W
a5 0 4 0 2 W
a1 2 1 1 2 W
a2 2 0 1 2 F
就绪队列:a4、a5 、a1
完成队列:a2
Name cputime needtime count round state
a1 3 0 2 2 F
a2 2 0 1 2 F
a3 4 0 2 2 F
a4 2 0 1 2 F
a5 1 0 1 2 F
就绪队列:
完成队列:a2、a4、a5、a1、a3
二、优先数算法(带下划线表示输入)
输入:
input name and needtime:
a1 3
a2 2
a3 4
a4 2
a5 1
显示结果:
Name cputime needtime count pri state
a5 0 1 0 49 R
a2 0 2 0 48 W
a4 0 2 0 48 W
a1 0 3 0 47 W
a3 0 4 0 46 W
就绪队列:a2、a4、a1、a3
完成队列:
Name cputime needtime count pri state
a2 0 2 0 48 R
a4 0 2 0 48 W
a1 0 3 0 47 W
a3 0 4 0 46 W
a5 1 0 1 49 F
就绪队列:a4、a1、a3
完成队列:a5
Name cputime needtime count pri state
a4 0 2 0 48 R
a1 0 3 0 47 W
a3 0 4 0 46 W
a2 2 0 1 48 F
a5 1 0 1 49 F
就绪队列:a1、a3
完成队列:a5、a2
Name cputime needtime count pri state
a1 0 3 0 47 R
a3 0 4 0 46 W
a4 2 0 1 48 F
a2 2 0 1 48 F
a5 1 0 1 49 F
就绪队列:a3、a2 、a4
完成队列:a5、a2、a4
Name cputime needtime count pri state
a5 1 0 1 49 F
a2 2 0 1 48 F
a4 2 0 1 48 F
a1 3 0 2 44 F
a3 4 0 2 43 F
就绪队列:
完成队列:a5、a2、a4、a1、a3
一、时间片轮转法
代码演示:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<malloc.h>
#include<string.h>
#define N 10 //定义最大进程数
#define round 2//定义时间片大小
int num = 1;//记录进程执行次数
//定义队列结点数据类型
typedef struct pcb {
char Name[10];//进程标识数
int cuptime;//进程已经占用的cpu时间
int needtime;//进程还需要的时间
int count;//进程已经转的轮数
char state;//进程运行状态:R or W
struct pcb* next;
}pcb, * PCB;
//定义队列数据类型
typedef struct queue
{
int count;//当前队列的进程总数
PCB head, tail;//队头
}QUEUE, * PQUEUE;
//初始化队列结点
PCB creatQueueNode(int i)
{
PCB newNode = (PCB)malloc(sizeof(pcb));
printf("输入进程%d的标示符:", i);
scanf("%s", newNode->Name);
getchar();
printf("输入进程%d还需要的cpu时间:", i);
scanf("%d", &newNode->needtime);
getchar();
newNode->count = 0;
newNode->cuptime = 0;
newNode->state = 'W';
newNode->next = NULL;
return newNode;
}
//入队
void QueueEn(PQUEUE queue, PCB newNode)
{
if (queue == NULL)
{
return;
}
if (queue->count == 0)
{
queue->head = queue->tail = newNode;
}
else
{
queue->tail->next = newNode;
queue->tail = newNode;
}
queue->count++;
return;
}
//出队
void QueueOut(PQUEUE queue)
{
if (queue == NULL || queue->count == 0)
{
return;
}
PCB temp = queue->head->next;
free(queue->head);
queue->head = temp;
queue->count--;
return;
}
//创建进程队列
PQUEUE InitQueueProcess(int n)
{
PQUEUE queue = (PQUEUE)malloc(sizeof(QUEUE));
queue->head = queue->tail = NULL;
queue->count = 0;
int i = 0;
for (i = 1; i <= n; i++)
{
PCB newNode = creatQueueNode(i);//创建并初始化队列结点
QueueEn(queue, newNode);//入队
}
return queue;
}
//展示当前进程结果
void showQueue(PQUEUE queue, PQUEUE queue_1)
{
printf("\n\n**************第%d次执行进程状态********************\n", num);
printf("Name cpuround needtime count round state\n");
PCB pMove = queue->head;
while (pMove)
{
printf("%s\t%d\t%d\t %d\t %d\t%c\n",///
pMove->Name, pMove->cuptime, pMove->needtime, pMove->count, 2, pMove->state);
pMove = pMove->next;
}
pMove = queue_1->head;
while (pMove)
{
printf("%s\t%d\t%d\t %d\t %d\t%c\n",
pMove->Name, pMove->cuptime, pMove->needtime, pMove->count, 2, pMove->state);
pMove = pMove->next;
}
//输出就绪队列
printf("就绪队列:");
pMove = queue->head;
while (pMove)
{
if (pMove->state == 'W')
printf("%s、", pMove->Name);
pMove = pMove->next;
}
printf("\n");
//输出完成队列
printf("完成队列:");
pMove = queue_1->head;
while (pMove)
{
printf("%s、", pMove->Name);
pMove = pMove->next;
}
printf("\n\n**************************************************\n");
return;
}
//每执行一次进程就输出一次就绪队列的结果
void RunProcess(PQUEUE queue, PQUEUE queue_1)
{
if (queue == NULL || queue->count == 0)
return;
//当进程未全部执行完毕时,一直执行
while (queue->head != NULL)
{
//执行一次队头进程
PCB pMove = queue->head;
pMove->state = 'R';
//显示当前队列状态
showQueue(queue, queue_1);
if (pMove->needtime > 0)
{
pMove->cuptime += round;
pMove->needtime -= round;
//计算是否完成
if (pMove->needtime <= 0)
{
pMove->needtime = 0;
}
}
//深拷贝队头结点
PCB temp = (PCB)malloc(sizeof(pcb));
temp->count = pMove->count;
temp->cuptime = pMove->cuptime;
strcpy(temp->Name, pMove->Name);
temp->needtime = pMove->needtime;
temp->state = pMove->state;
temp->next = NULL;
if (temp->needtime == 0)
{
//temp入完成队列
temp->state = 'F';
QueueEn(queue_1, temp);
if (queue->count == 1)
{
num++;
QueueOut(queue);
showQueue(queue, queue_1);
return;
}
}
else
{
//temp入就绪队列
temp->state = 'W';
QueueEn(queue, temp);
}
temp->count++;//执行次数加一
//队头出队
QueueOut(queue);
num++;
}
return;
}
int main() {
//创建就绪队列进程
printf("输入你要创建的进程数:");
int n;
scanf("%d", &n);
getchar();
PQUEUE readyQueue = InitQueueProcess(n);
PQUEUE compeletQueue = InitQueueProcess(0);
printf("\n\n");
//执行队列进程
RunProcess(readyQueue, compeletQueue);//简单轮转法Round Robin
return;
}
输入:
输出:
二、优先数算法:
代码演示:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define round 2//定义时间片大小
int num = 1;//记录进程执行次数
//定义队列结点数据类型
typedef struct pcb {
char Name[10];//进程名称
int cuptime;//进程已经占用的cpu时间
int needtime;//进程还需要的时间
int count;//进程已经转的轮数
int pri;//进程的优先数
char state;//进程运行状态:R or W or F
struct pcb* next;
}pcb, * PCB;
//定义队列数据类型
typedef struct queue
{
int count;//当前队列的进程总数
PCB head, tail;//队头
}QUEUE, * PQUEUE;
//初始化队列结点
PCB creatQueueNode(int i)
{
PCB newNode = (PCB)malloc(sizeof(pcb));
printf("输入进程%d的标示符:", i);
scanf("%s", newNode->Name);
getchar();
printf("输入进程%d还需要的cpu时间:", i);
scanf("%d", &newNode->needtime);
getchar();
newNode->pri = 50 - newNode->needtime;//初始化优先数
newNode->count = 0;
newNode->cuptime = 0;
newNode->state = 'W';
newNode->next = NULL;
return newNode;
}
//入队
void QueueEn(PQUEUE queue, PCB newNode)
{
if (queue == NULL)
{
return;
}
if (queue->count == 0)
{
queue->head = queue->tail = newNode;
}
else
{
queue->tail->next = newNode;
queue->tail = newNode;
}
queue->count++;
return;
}
//出队
void QueueOut(PQUEUE queue)
{
if (queue == NULL || queue->count == 0)
{
return;
}
PCB temp = queue->head->next;
free(queue->head);
queue->head = temp;
queue->count--;
return;
}
//创建进程队列
PQUEUE InitQueueProcess(int n)
{
PQUEUE queue = (PQUEUE)malloc(sizeof(QUEUE));
queue->head = queue->tail = NULL;
queue->count = 0;
int i = 0;
for (i = 1; i <= n; i++)
{
PCB newNode = creatQueueNode(i);//创建并初始化队列结点
QueueEn(queue, newNode);//入队
}
return queue;
}
//排序,仅交换队列结点的值
void sortQueue(PQUEUE queue)
{
int i = 0, j = 0;
int n;
for (i = 0; i < queue->count - 1; i++)
{
for (j = 0; j < queue->count - 1 - i; j++)
{
PCB pMove = queue->head;
n = 0;
while (n < j)
{
pMove = pMove->next;
n++;
}
PCB pMoveNext = pMove->next;
if (pMove->pri < pMoveNext->pri)
{
int t_count = pMove->count;
int t_cuptime = pMove->cuptime;
char t_Name[10];
strcpy(t_Name, pMove->Name);
int t_needtime = pMove->needtime;
int t_pri = pMove->pri;
char t_state = pMove->state;
pMove->count = pMoveNext->count;
pMove->cuptime = pMoveNext->cuptime;
strcpy(pMove->Name, pMoveNext->Name);
pMove->needtime = pMoveNext->needtime;
pMove->pri = pMoveNext->pri;
pMove->state = pMoveNext->state;
pMoveNext->count = t_count;
pMoveNext->cuptime = t_cuptime;
pMoveNext->needtime = t_needtime;
strcpy(pMoveNext->Name, t_Name);
pMoveNext->pri = t_pri;
pMoveNext->state = t_state;
}
}
}
return;
}
//展示当前进程结果
void showQueue(PQUEUE queue, PQUEUE queue_1)
{
printf("\n\n**************第%d次执行进程状态********************\n", num);
printf("Name cpuround needtime count pri state\n");
PCB pMove = queue->head;
while (pMove)
{
printf("%s\t%d\t%d\t %d\t %d\t%c\n",///
pMove->Name, pMove->cuptime, pMove->needtime, pMove->count, pMove->pri, pMove->state);
pMove = pMove->next;
}
pMove = queue_1->head;
while (pMove)
{
printf("%s\t%d\t%d\t %d\t %d\t%c\n",
pMove->Name, pMove->cuptime, pMove->needtime, pMove->count, pMove->pri, pMove->state);
pMove = pMove->next;
}
//输出就绪队列
printf("就绪队列:");
pMove = queue->head;
while (pMove)
{
if (pMove->state == 'W')
printf("%s、", pMove->Name);
pMove = pMove->next;
}
printf("\n");
//输出完成队列
printf("完成队列:");
pMove = queue_1->head;
while (pMove)
{
printf("%s、", pMove->Name);
pMove = pMove->next;
}
printf("\n\n**************************************************\n");
return;
}
//优先数算法
void RunProcess(PQUEUE queue, PQUEUE queue_1)
{
if (queue == NULL || queue->count == 0)
return;
//当进程未全部执行完毕时,一直执行
while (queue->head != NULL)
{
//对进程优先数进行排序
sortQueue(queue);
//执行一次队头进程
PCB pMove = queue->head;
pMove->state = 'R';
//显示当前队列状态
showQueue(queue, queue_1);
if (pMove->needtime > 0)
{
pMove->cuptime += round;
pMove->needtime -= round;
//计算是否完成
if (pMove->needtime <= 0)
{
pMove->needtime = 0;
}
}
//深拷贝队头结点
PCB temp = (PCB)malloc(sizeof(pcb));
temp->count = pMove->count;
temp->cuptime = pMove->cuptime;
strcpy(temp->Name, pMove->Name);
temp->needtime = pMove->needtime;
temp->pri = pMove->pri;
temp->state = pMove->state;
temp->next = NULL;
if (temp->needtime == 0)
{
//temp入完成队列
temp->state = 'F';
QueueEn(queue_1, temp);
if (queue->count == 1)
{
num++;
QueueOut(queue);
showQueue(queue, queue_1);
return;
}
}
else
{
//temp入就绪队列
temp->pri -= 3;//优先数-3
temp->state = 'W';
QueueEn(queue, temp);
}
temp->count++;//执行次数加一
//队头出队
QueueOut(queue);
num++;
}
return;
}
int main(int argc, char* argv[])
{
//创建就绪队列进程
printf("输入你要创建的进程数:");
int n;
scanf("%d", &n);
getchar();
PQUEUE readyQueue = InitQueueProcess(n);
PQUEUE compeletQueue = InitQueueProcess(0);
printf("\n\n");
//执行队列进程
RunProcess(readyQueue, compeletQueue);//简单轮转法Round Robin
return 0;
}
输入:
输出:
如果有啥问题可以留言交流,我一定及时回复;