操作系统实验(二):进程调度(c实现优先权调度和时间片轮转调度)

本文通过详细介绍进程控制块和队列概念,指导读者实现优先权调度和时间片轮转算法。涉及PCB设计、进程创建、调度逻辑和代码实现,适合学习操作系统原理与调度技术。

一、【实验目的】
①理解有关进程控制块、进程队列的概念。
②掌握进程优先权调度算法和时间片轮转调度算法的处理逻辑。
二、【实验内容】
①设计进程控制块PCB的结构,分别适用于优先权调度算法和时间片轮转调度算法。
②建立进程就绪队列。
③编制两种进程调度算法:优先权调度和时间片轮转调度。
三、【实验步骤】
数据结构:
struct pcb //进程控制块数据结构
{
char name [4];//进程名
int priority;//优先权
int cpuTime;//CPU运行时间
int needTime;//进程运行所需时间
int count;//进程执行次数
int round;//时间片轮转轮次
enum state process;//进程状态
struct pcb* next; //链表指针
};//定义进程PCB

struct pcb* getProcess()
{
struct pcb* q = NULL;
struct pcb* t = NULL;
struct pcb* p = NULL;

struct pcb* getProcessRound()
{
struct pcb* q = NULL;
struct pcb* t = NULL;
struct pcb* p = NULL;

struct pcb* GetNext(struct pcb* k, struct pcb* head)
{
struct pcb* t;

实验代码:

#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<windows.h>
#define RNUM 5 //5个进程,可改变
#define PTIME 50 //优先级初始值 

enum state //枚举类型 
{
 ready, //就绪 
 execute, //执行 
 block, //阻塞 
 finish //完成 
};//定义进程状态

struct pcb //进程控制块数据结构 
{
 char name [4];//进程名
 int priority;//优先权
 int cpuTime;//CPU运行时间
 int needTime;//进程运行所需时间
 int count;//进程执行次数
 int round;//时间片轮转轮次
 enum state process;//进程状态
 struct pcb* next; //链表指针 
};//定义进程PCB

struct pcb* getProcess()
{
 struct pcb* q = NULL;
 struct pcb* t = NULL;
 struct pcb* p = NULL;
 int  i = 0;
 printf("请输入进程的名称和运行时间!\n");
 while(i < RNUM)
 {
  q=(struct pcb* )malloc(sizeof(struct pcb));
  scanf("%s", &q->name);
  scanf("%d", &q->needTime);
  q->cpuTime = 0;
  q->priority = PTIME - q->needTime; 
  q->process = ready;
  q->next = NULL;
  if(i == 0)
  {
   p = q;
   t = q;
  } 
  else
  {
   t->next = q;//创建就绪进程队列
   t = q;
     }
  i++;
 } 
  return p;
  
}//输入模拟测试的进程名和执行所需时间,初始设置可模拟5个进程的调度

void display(struct pcb* p)
{
 printf("名称\t进程运行时间\t进程所需时间\t\t优先级\t\t状态\n");
 while(p)
 {
  printf("%s\t", p->name);  //输出进程名
  printf("        ");
  printf("%d\t", p->cpuTime); //输出cpu执行时间
  printf("        "); 
  printf("%d\t", p->needTime);//输出进程执行所需时间
  printf("        "); 
  printf("%d\t", p->priority);//输出优先级
  printf("         "); 
  switch(p->process)//输出进程状态 
  {
   case ready:
    printf("就绪\n");
    break;
   case execute:
    printf("执行\n");
    break;
   case block:
    printf("阻塞\n");
    break;
   case finish:
    printf("完成\n");
    break;
   default:
    break;
  }
  p = p->next;//指向下一个进程 
 }//显示模拟结果,包含进程名、CPU时间、运行所需时间以及优先级
}

int processFinish(struct pcb* q)//进程是否结束,当还有进程没有结束时返回0 
{
 int bl = 1;
 while(bl && q)
 {
  bl = bl && (q->needTime == 0);
  q = q->next;
 }
 return bl; 
 
}//结束进程,即将队列中各进程的所需时间设置为0

void couExe(struct pcb* q)
{
 struct pcb* t = q;
 int maxPriority = 0; //设最大优先级为0 
 while(q)
 {
  if(q->process != finish)
  {
   q->process = ready;
   if(q->needTime == 0)
   {
    q->process = finish;
   }
  }
  if(maxPriority < q->priority && q->process != finish)
  {
   maxPriority = q->priority;
   t = q;
  }
  q = q->next; //指向下一个进程 
 }
 if(t->needTime != 0)//如果q的所需时间不为0 
 {
  t->priority -= 3;//优先级=优先级-3 
  t->needTime--;//所需时间-1 
  t->process = execute;//进程阻塞 
  t->cpuTime++; //cup执行时间+1 
 }
}
//选择某一进程,给它分配CPU
//计算进程优先级

void priorityCal(void)  //优先数调度 
{
 struct pcb* p = NULL;
 system("cls");
 p = getProcess();
 int cpu = 0;
 system("cls");
 while(!processFinish(p))
 {
  cpu++;
  printf("cpuTime:%d\n",cpu);//输出cpu运行时间 
  couExe(p);
  display(p);
  Sleep(2);
  //system("cls");
  //clrscr();
 }
 
 printf("所有进程已经执行完毕,按任意键退出!");
 getchar();
}

void displayMenu(void)
{
 printf("请选择一个算法:\n\n");
 printf("1 动态优先级算法\n\n");
 printf("2 时间片轮转算法\n\n");
 printf("3 退出\n\n");
}//显示调度算法菜单,可供用户选择优先权调度算法和时间片轮转调度算法

struct pcb* getProcessRound()
{
 struct pcb* q = NULL;
 struct pcb* t = NULL;
 struct pcb* p = NULL;
 int i = 0;
 printf("请输入进程名称和进程运行时间:\n");
 while(i < RNUM) //5个进程进行轮转 
 {
  q = (struct pcb* )malloc(sizeof(struct pcb)); //分配空间 
  scanf("%s", &(q->name));//输入进程名 
  scanf("%d", &(q->needTime));//输入进程执行所需时间 
  q->cpuTime = 0;
  q->priority = PTIME - (q->needTime);
  q->process = ready; //让进程处于就绪状态 
  q->round = 0;
  q->count = 0;
  q->next = NULL;  
  if(i == 0)
  {
   p = q;
   t = q;
  }
  else
  {
   t->next = q;
   t = q;
  }
  i++;
 }
 return p;
 
}//时间片轮转调度算法创建就绪进程队列

void cpuRound(struct pcb* q)
{
 q->cpuTime += 2;
 q->needTime -= 2;
 
 if(q->needTime < 0)
 {
  q->needTime = 0;
 }
 q->count++;
 q->round++;
 q->process = execute; //进程进入执行状态 
}//采用时间片轮转调度算法执行某一进程

struct pcb* GetNext(struct pcb* k, struct pcb* head)
{
 struct pcb* t;
 t = k;
 do
 {
  t = t->next;
 }
 while(t && t->process == finish);
 if(t == NULL)
 {
  t = head;
  while(t->next != k && t->process == finish)
  {
   t = t->next;
  }
 }
 return t;
 
}//获取下一个进程

void setState(struct pcb* p)
{
 while(p)
 {
  if(p->needTime == 0)
  {
   p->process = finish;//如果所需执行时间为0,则设置运行状态为结東
  }
  if(p->process == execute)
  {
   p->process = ready;//如果为执行状态则设置为就绪
  }
  p = p->next;
 }
}//设置队列中进程执行状态

void displayRound(struct pcb* p)
{
 printf("进程名称\t进程运行时间\t进程所需时间\t进程执行次数\t轮转次数\t状态\n");
 while(p)
 {
  printf("%s\t\t",p->name);
  printf("      ");
  printf("%d\t\t",p->cpuTime);
  printf("      ");
  printf("%d\t\t",p->needTime);
  printf("      ");
  printf("%d\t\t",p->count);
  printf("      ");
  printf("%d\t\t",p->round);
  printf("      ");
  switch(p->process)
  {
   case ready:
    printf("就绪\n");
    break;
   case execute:
    printf("执行\n");
    break;
   case finish:
    printf("完成\n");
    break;
  }
  p = p->next; //跳向下一个进程 
 }
}//时间片轮转调度算法输出调度信息

void roundCal() //循环轮转调度 
{
 struct pcb* p;
 struct pcb* r;
 p = getProcessRound();
 int cpu = 0;
  r = p;
 while(!processFinish(p))
 {
  cpu += 2;
  cpuRound(r);
  r = GetNext(r, p);
  printf("cpu %d\n", cpu);
  displayRound(p);
  setState(p);
  Sleep(5);
 }
}//时间片轮转调度算法计算轮次及输出调度信息

int main()
{
 displayMenu();
 int userInput = 0;
 scanf("%d", &userInput);
 switch(userInput)
 {
  case 1:
   priorityCal();
   break;
  case 2:
   roundCal();
   break;
  case 3:
   break;
  displayMenu();
  scanf("%d", &userInput);
 }
}

结果自行运行~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值