实验原理和方法
1.
进程(Process)是计算机中的程序关于其数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。
1)动态性、并发性、独立性、异步性。
2)程序是静态的概念,进程是程序在处理机上的一次执行过程,它是一个动态的概念。
3)进程由程序、数据和进程控制块PCB三部分组成。
4)运行中的进程可能具有以下三种基本状态:就绪、运行、等待。
2. 进程控制是进程管理中最基本的功能。它用于创建一个进程,终止或撤销一个进程,还负责进程运行过程中的状态转换。
3.
实验是模拟性质的实验,即不以真实的操作系统的系统调用及其各种数据结构进行操作。在程序中创建一个记录数组以作为进程的PCB结构来进行有关的操作。通过模拟进程的创建、初始化、修改进程控制块的状态标志,实现对进程管理的简单模拟。
4. 实验采用的进程调度策略:简单的时间片轮转算法RR。
1)时间片轮转算法RR:每个进程被分配一个时间段,又称为时间片,也就是该进程允许运行的时间。如果在时间片结束时,进程还没运行完,则CPU被分派给另一个就绪的进程。如果运行中的进程在时间片结束前被等待或运行结束,则CPU进行切换。
主要数据结构的定义和描述
//计时器
typedef struct _time {
int seconds; //秒
int minutes; //分
int hours; //时
}TIME,*LPTime;
//进程控制块
typedef struct Node{
int pid;
int time_need;
int time_used;
char status;
struct Node *pNext;
}Node,*PCB;
程序模块构成
1)时间控制模块。
2)进程变迁模块。
3)输出模块。
主要算法的模型或描述
运用一个计时器(秒表)来记录时间,每三秒生成若干进程(可以不生成)。
程序主体:
for(;;) {//死循环来记录时间
special = random(5);//特殊事件
wakeup = random(5);//唤醒事件
UpdateTime(systemtime);//不断更新时间
if(pReady->pNext == NULL && pRun->pNext == NULL
&& pBlock->pNext == NULL){//就绪、运行、阻塞队列全空,退出程序
exit(1);
}
//每三秒创建若干进程
if(miao % 30 == 0){
update_ready(pReady);
}
//运行队列空,就绪队列进程被调度
if(pRun->pNext == NULL && pReady->pNext != NULL
){
ready_run(pReady,pRun);
run(pRun);
}
//时间片消耗
if(pRun->pNext != NULL){
pRun->pNext->time_used ;
//时间片耗完
if(pRun->pNext->time_used % 60 == 0){
timeout(pReady,pRun);
ready(pReady);
}
//进程完成
if( pRun->pNext->time_used >=
pRun->pNext->time_need){
run_finish(pRun,pFinish);
finish(pFinish);
}
}
//特殊事件发生,进程等待事件
if(special == 0 && pRun->pNext != NULL ){
run_block(pRun,pBlock);
block(pBlock);
}
//唤醒事件发生,阻塞进程被唤醒
if(wakeup == 1 && pBlock->pNext != NULL){
Block_ready(pBlock,pReady);
ready(pReady);
}
//每1/10s执行依次循环
Sleep(100);
}
程序运行的主要画面截图及其说明
初始状态:5个就绪进程(图1)。
图 1
当运行队列为空时,发生调度。就绪队列对头自动进入运行队列,随之发生状态改变(r->e)图2)。
图 2
时间片消耗完,运行进程进入就绪队列,随之状态改变(e->f)(图3)
图 3
当发生特殊事件时(如请求I/O),运行进程进入阻塞队列,随之发生状态改变(e->b)
(图4,图 5)。.
图4
图 5
每三秒生成若干进程(生成了1个进程)(图6)
图 6
当发生唤醒事件时,阻塞进程进入就绪队列,随之发生状态改变(b->r)
图 7
程序执行完成(图8)。
图 8
源程序代码
#include
#include
#include
#include
#include
#include
#include
int id = 1;
int miao = 0; //该时间用来记录每3S生成若干进程
int timeSlice = 0; //该时间 用来记录时间片
int special = 0; //特殊事件(请求I/O等)
int wakeup = 0; //唤醒事件
//时间
typedef struct _time {
int seconds;
int minutes;
int hours;
}TIME,*LPTime;
//进程
typedef struct Node{
int pid;
int time_need;
int time_used;
char status;
struct Node *pNext;
}Node,*PCB;
//初始化时间表
LPTime InitTime(LPTime time)
{
time=(LPTime)malloc(sizeof(TIME));
if (!time)
{
printf("Error!!!\n");
exit(0);
}
time->hours =0;
time->minutes =0;
time->seconds =0;
return time;
}
//更新时间
void UpdateTime(LPTime time)
{
time->seconds ;
timeSlice ;
miao ;
timeSlice ;
if(time->seconds==10)
{
time->seconds=0;
time->minutes ;
}
if(time->minutes==60)
{
time->minutes=0;
time->hours ;
}
}
//显示时间
void ShowTime(LPTime time)
{
printf("d:",time->hours);
printf("d:",time->minutes);
printf("d\r",time->seconds);
}
//产生随机数
int random(int a){
int i;
srand((int)time(0));
return
rand() % a;
}
//创建进程
PCB fork(int n)
{
int
i, len, val;
PCB
pHead = (PCB)malloc(sizeof(Node));
len
= n;
PCB
pTail = pHead;
pTail->pNext
= NULL;
for(i=0;
i
{
PCB
pNew = (PCB)malloc(sizeof(Node));
pNew->pid
= id ;
pNew->status
= 'r';
pNew->time_need
= random(20);
pNew->time_used
= 0;
pTail->pNext
= pNew;
pNew->pNext
= NULL;
pTail
= pNew;
}
return
pHead;
}
//显示进程队列
void view(PCB pHead)
{
PCB
p = pHead->pNext;
while(p
!= NULL) {
printf("
%d %d %d %c\n",
p->pid,p->time_need,p->time_used,p->status);
p
= p->pNext;
}
printf("\n");
return;
}
void viewShow(PCB pReady, PCB pRun, PCB pBlock,PCB
pFinish)
{
printf(" id time_need time_used status\n");
printf("Ready:
\n");
view(pReady);
printf("Run:
\n");
view(pRun);
printf("Block:
\n");
view(pBlock);
printf("Finish:
\n");
view(pFinish);
printf("\n");
}
//创建若干新的进程(可以不创建进程)
void update_ready(PCB pHead){
PCB p = pHead;
while(p->pNext != NULL) p = p->pNext;
PCB pNew = (PCB)malloc(sizeof(Node));
pNew = fork(random(3));
if (!pNew) return;
else p->pNext = pNew->pNext;
}
//进程调度
void ready_run(PCB pReady,PCB pRun){
PCB p = pReady;
PCB q = pRun;
if(p == NULL) return;
else{
PCB pNew = (PCB)malloc(sizeof(Node));
while(q->pNext != NULL) q = q->pNext;
pNew = p->pNext;
p->pNext = pNew->pNext;
pNew->pNext = NULL;
q->pNext = pNew;
}
}
//时间片到
void timeout(PCB pReady,PCB pRun) {
PCB p = pReady;
PCB q = pRun;
if(q == NULL) return;
else{
PCB pNew = (PCB)malloc(sizeof(Node));
while(p->pNext != NULL) p = p->pNext;
pNew = q->pNext;
q->pNext = pNew->pNext;
pNew->pNext = NULL;
p->pNext = pNew;
}
}
//进程等待事件
void run_block(PCB pRun,PCB pBlock){
PCB p = pRun;
PCB q = pBlock;
if(p == NULL) return;
else {
while(q->pNext != NULL) q = q->pNext;
q->pNext = p->pNext;
p->pNext = NULL;
}
}
//唤醒事件
void Block_ready(PCB pBlock, PCB pReady) {
PCB p = pBlock;
PCB q = pReady;
if(p == NULL) return;
else{
PCB pNew = (PCB)malloc(sizeof(Node));
while(q->pNext != NULL) q = q->pNext;
pNew = p->pNext;
p->pNext = pNew->pNext;
pNew->pNext = NULL;
q->pNext = pNew;
}
}
//进程完成
void run_finish(PCB pRun,PCB pFinish){
PCB p = pRun;
PCB q = pFinish;
if(p == NULL) return;
else{
while(q->pNext != NULL) q = q->pNext;
q->pNext = p->pNext;
p->pNext = NULL;
}
}
//进程就绪
void ready(PCB pReady){
PCB p = pReady->pNext;
while(p != NULL){
p->status = 'r';
p = p->pNext;
}
}
//进程运行
void run(PCB pRun){
PCB p = pRun->pNext;
p->status = 'e';
}
//进程完成
void finish(PCB pFinish){
PCB p = pFinish->pNext;
while(p != NULL){
p->status = 'f';
p = p->pNext;
}
}
//进程等待
void block(PCB pBlock){
PCB p = pBlock->pNext;
while(p != NULL){
p->status = 'b';
p = p->pNext;
}
}
int main(){
PCB pReady,pRun,pBlock,pFinish; //声明就绪,运行,阻塞,完成队列
pReady = pRun = pBlock = pFinish = NULL;
pReady = fork(5);//创建就绪队列
pRun = fork(0);//创建运行队列
pBlock = fork(0);//创建等待队列
pFinish = fork(0);//创建完成队列
viewShow(pReady,pRun,pBlock,pFinish);
LPTime systemtime=0;//初始化时间
systemtime=InitTime(systemtime);
//程序运行,时间开始
for(;;) {
special = random(10);//特殊事件
wakeup = random(5);//唤醒事件
UpdateTime(systemtime);//不断更新时间
if(pReady->pNext == NULL && pRun->pNext == NULL
&& pBlock->pNext == NULL){
exit(1);
}
//每三秒创建若干进程
if(miao % 30 == 0){
update_ready(pReady);
viewShow(pReady,pRun,pBlock,pFinish);
getchar();
}
//运行队列空,就绪队列进程被调度
if(pRun->pNext == NULL && pReady->pNext != NULL
){
ready_run(pReady,pRun);
run(pRun);
viewShow(pReady,pRun,pBlock,pFinish);
getchar();
}
//时间片消耗,6S
if(pRun->pNext != NULL){
pRun->pNext->time_used ;
//时间片耗完
if(pRun->pNext->time_used % 60 == 0){
timeout(pReady,pRun);
ready(pReady);
viewShow(pReady,pRun,pBlock,pFinish);
getchar();
}
//进程完成
if( pRun->pNext->time_used >=
pRun->pNext->time_need){
run_finish(pRun,pFinish);
finish(pFinish);
viewShow(pReady,pRun,pBlock,pFinish);
getchar();
}
}
//特殊事件发生,进程等待事件
if(special == 0 && pRun->pNext != NULL ){
run_block(pRun,pBlock);
block(pBlock);
viewShow(pReady,pRun,pBlock,pFinish);
getchar();
}
//唤醒事件发生,阻塞进程被唤醒
if(wakeup == 1 && pBlock->pNext != NULL){
Block_ready(pBlock,pReady);
ready(pReady);
viewShow(pReady,pRun,pBlock,pFinish);
getchar();
}
Sleep(100);
}
return 0;
}