進程調度模擬
一、 實驗目的
用高級語言編寫和調試一個進程調度程序,以加深對進程的概念及進程調度算法的理解。
二、 實驗工具
Windows系統 + VisuaStudio2019
三、 實驗步驟
(1)進程調度程序要求
進程調度算法:採用最高優先數優先的調度算法(即把處理機分配給優先數最高的進程)和先來先服務算法。
每個進程有一個進程控制塊(PCB)表示。進程控制塊可以包含如下信息:進程名、優先數、到達時間、需要運行時間、已用CPU時間、進程狀態等等。
進程的優先數及需要的運行時間可以事先人爲的指定(也可以由隨機數產生)。進程的到達時間爲進程輸入的時間。
進程的運行時間以時間片爲單位進行計算。
每個進程的狀態可以是就緒 W(Wait)、運行R(Run)、或完成F(Finish)三種狀態之一。
就緒進程獲得CPU後都只能運行一個時間片。用已佔用CPU時間加1來表示。
如果運行一個時間片後,進程的已佔用 CPU時間已達到所需要的運行時間,則撤消該進程,如果運行一個時間片後進程的已佔用CPU時間還未達所需要的運行時間,也就是進程還需要繼續運行,此時應將進程的優先數減1(即降低一級),然後把它插入就緒隊列等待CPU。
每進行一次調度程序都打印一次運行進程、就緒隊列、以及各個進程的 PCB,以便進行檢查。
重複以上過程,直到所有進程都完成爲止
四、 實驗結果
代碼段:
#define _CRT_SECURE_NO_WARNINGS
#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 super;
int ntime;
int rtime;
struct pcb* link;
}*ready = NULL, * p;
typedef struct pcb PCB;
void sort() /* 建立對進程進行優先級排列函數*/
{
PCB* first, * second;
int insert = 0;
if ((ready == NULL) || ((p->super) > (ready->super))) /*優先級最大者,插入隊首*/
{
p->link = ready;
ready = p;
}
else /* 進程比較優先級,插入適當的位置中*/
{
first = ready;
second = first->link;
while (second != NULL)
{
if ((p->super) > (second->super)) /*若插入進程比當前進程優先數大,*/
{ /*插入到當前進程前面*/
p->link = second;
first->link = p;
second = NULL;
insert = 1;
}
else /*向後移動指針*/
{
first = first->link;
second = second->link;
}
}
/* 插入進程優先數最低,則插入到隊尾*/
if (insert == 0) first->link = p;
}
}
void input() /* 建立進程控制塊函數*/
{
int i, num;
system("cls"); /*清屏*/
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->super);
printf("\n 輸入進程運行時間:");
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);
}
void disp(PCB* pr) /*建立進程顯示函數,用於顯示當前進程*/
{
printf("\n qname \t state \t super \t ndtime \t runtime \n");
printf("|%s\t", pr->name);
printf("|%c\t", pr->state);
printf("|%d\t", pr->super);
printf("|%d\t", pr->ntime);
printf("|%d\t", pr->rtime);
printf("\n");
}
void check() /* 建立進程查看函數 */
{
PCB* pr;
printf("\n **** 當前正在運行的進程是:%s", p->name); /*顯示當前運行進程*/
disp(p);
pr = ready;
printf("\n ****當前就緒隊列狀態爲:\n"); /*顯示就緒隊列狀態*/
while (pr != NULL)
{
disp(pr);
pr = pr->link;
}
}
void destroy() /*建立進程撤消函數(進程運行結束,撤消進程)*/
{
printf("\n 進程 [%s] 已完成.\n", p->name);
free(p);
}
void running() /* 建立進程就緒函數(進程運行時間到,置就緒狀態*/
{
(p->rtime)++;
if (p->rtime == p->ntime)
destroy(); /* 調用destroy函數*/
else
{
(p->super)--;
p->state = 'w';
sort(); /*調用sort函數*/
}
}
void 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();
}