时间片轮转调度算法:每个进程被分配一个时间片,即允许该进程在该时间段中运行。如果在时间片结束时该进程还在运行,则将剥夺CPU分配给另一个进程。如果该进程在时间片结束前阻塞或结束,则CPU立即进行切换。

优先调度算法:每个进程被赋予一个优先级,允许优先级最高的可运行进程先运行,调度程序可以在每个时钟滴答(即每个时钟中断)降低当前的进程优先级。

OSprocess.h

#ifndef _OSprocess_H_
#define _OSprocess_H_

enum {READY, RUNNING}; //进程运行状态
enum {RR, SPF}; //算法选择

typedef struct _Pcb
{
int pid; /*进程ID*/
char name[20]; /*进程名*/

int state; /*进程状态*/
int priority; /*进程优先级*/

int tArriving; /*到达时间*/
int tOverall; /*运行时间*/
int tRunning; /*已运行时间*/

}Pcb;

typedef struct _PcbQueue
{
Pcb *block; /*Pcb数据域*/
struct _PcbQueue *next; /*指针域*/
}PcbQueue;

typedef struct _PPQueue
{
PcbQueue *head;
PcbQueue *tail;
}PPQueue;

//typedef struct _GQueues
//{
// PPQueue qFree; /*空余队列*/
// PPQueue qReady; /*就绪队列*/
//}GQueues;

/*分配的最大空余PCB块数*/
#define MAX_PCB_NUM 10
extern Pcb pcbBlock[MAX_PCB_NUM];

#endif



OSPPQueue.h

#ifndef _OSGQueue_H_
#define _OSGQueue_H_

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

#include "OSprocess.h"
#include "OSQueue.h"

/* 初始化PCB块和空余队列 */
int InitGQueues(PPQueue *gq)
{
 gq->tail = gq->head = NULL;

 return 0;
}

/* 分配PCB内存块 */
int allocPcb(PPQueue *gq, int pid, int tServing, int tArriving)
{
 Pcb *Node = (Pcb *)malloc(sizeof(Pcb));

 Node->pid = pid;
 Node->state = 0;
 Node->tArriving = tArriving;
 Node->tOverall = tServing;
 Node->tRunning = 0;

 enQueue(gq,Node);

 return 0;
}

/* RR算法 */
void invokeRR(PPQueue *qReady, PPQueue *qFree)
{
 Pcb *data = (Pcb *)malloc(sizeof(Pcb));
 data = DeQueue(qReady);
 if (data->tRunning == data->tOverall)
 {
  enQueue(qFree,data);
 }
 else
 {
  enQueue(qReady,data);
 }
}
/* SPF算法 */
int invokeSpf(PPQueue *qReady, PPQueue *qFree)
{
 int pid = 0;
 PcbQueue *Node = (PcbQueue *)malloc(sizeof(PcbQueue));
 Pcb *data = (Pcb *)malloc(sizeof(Pcb));

 Node = qReady->head;
 if (Node->block->tArriving == 0)
 {
  ++(Node->block->tRunning);
  pid = Node->block->pid;
  if (Node->block->tRunning == Node->block->tOverall)
  {
   data = DeQueue(qReady);
   enQueue(qFree,data);
  }
 }
 else
 {
  pid = -1;
 }
 while(Node != NULL)
 {
  if (Node->block->tArriving > 0)
  {
   Node->block->tArriving--;
  }
  Node = Node->next;
 }
 return pid;
}

/* 返回执行进程的pid, -1表示无就绪进程 */
int running(PPQueue *qReady, PPQueue *qFree)
{
 int pid = 0;
 PcbQueue *Node = (PcbQueue *)malloc(sizeof(PcbQueue));
 Pcb *data;

 Node = qReady->head;
 if (Node->block->tArriving == 0)
 {
  (Node->block->tRunning)++;
  pid = Node->block->pid;
  invokeRR(qReady,qFree);
 }
 else
 {
  pid = -1;

  if (Node->block->tArriving > 0)
  {
   Node->block->tArriving--;
   data = DeQueue(qReady);
   enQueue(qReady, data);
  }
 }
 return pid;
}

///* 队头进程是否结束,1为运行完毕 */
//int finishReadyHead(GQueues *gq)

#endif


OSQueue.h

#ifndef _OSQueue_H_
#define _OSQueue_H_

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

#include "OSprocess.h"

/* 创建队列 */
PcbQueue *creatPcb(Pcb *block)
{
 PcbQueue *Queue = (PcbQueue *)malloc(sizeof(PcbQueue));
 Queue->block = block;
 Queue->next = NULL;

 return Queue;
}

/* 添加队列 */
void enQueue(PPQueue *gq, Pcb *block)
{
 PcbQueue *Node = (PcbQueue *)malloc(sizeof(PcbQueue));
 Node->block = block;
 Node->next = NULL;

 if(gq->tail == NULL)
 {
  gq->head = gq->tail = Node;
 }
 else
 {
  gq->tail->next = Node;
  gq->tail = Node;
 }
}

/*出队列*/
Pcb *DeQueue(PPQueue *ptr)
{
 PcbQueue *Node;
 if(ptr->tail==NULL)
 {
  return NULL;
 }
 Node = ptr->head;
 if (ptr->head == ptr->tail)
 {
  ptr->head = ptr->tail = NULL;
 }
 else
 {
  ptr->head = ptr->head->next;
 }

 return Node->block;
}
/* 删除队列 */
void freeQueue(PPQueue *gq)
{
 PcbQueue *Node = gq->head;
 PcbQueue *ptr;

 if (Node != NULL)
 {
  ptr = Node->next;
  while(ptr!=NULL)
  {
   free(Node);
   Node = ptr;
   ptr = Node->next;
  }
 }
 free(gq);
}


#endif


OSprocess.h

#ifndef _OSprocess_H_
#define _OSprocess_H_

enum {READY, RUNNING};  //进程运行状态
enum {RR, SPF};    //算法选择

typedef struct _Pcb
{
 int pid;     /*进程ID*/
 char name[20];    /*进程名*/

 int state;     /*进程状态*/
 int priority;    /*进程优先级*/

 int tArriving;    /*到达时间*/
 int tOverall;    /*运行时间*/
 int tRunning;    /*已运行时间*/

}Pcb;

typedef struct _PcbQueue
{
 Pcb *block;     /*Pcb数据域*/
 struct _PcbQueue *next;  /*指针域*/
}PcbQueue;

typedef struct _PPQueue
{
 PcbQueue *head;
 PcbQueue *tail;
}PPQueue;

//typedef struct _GQueues
//{
// PPQueue qFree;   /*空余队列*/
// PPQueue qReady;   /*就绪队列*/
//}GQueues;

/*分配的最大空余PCB块数*/
#define MAX_PCB_NUM 10
extern Pcb pcbBlock[MAX_PCB_NUM];

#endif

OSsort.h

#ifndef _OSsort_H_
#define _OSsort_H_

#include <stdlib.h>

#include "OSsort.h"

/* 比较函数: 若pA > pB, 返回1; 否则返回0*/
int compare(Pcb *pA, Pcb *pB)
{
 return pB->tArriving < pA->tArriving;
}


/* 冒泡排序 */
void BubbleSort(PPQueue *qReady)
{
 PcbQueue *head = qReady->head;
 PcbQueue *next;
 Pcb *temp;

 while (head != qReady->tail)
 {
  next = head->next;
  while(next != NULL)
  {
   if (compare(head->block, next->block))
   {
    temp = head->block;
    head->block = next->block;
    next->block = temp;
   }
   next = next->next;
  }
  head = head->next;
 }
}

#endif

 

main.c


/*
* 实验1. 进程调度算法的设计
*
* 实验目的:通过对进程调度算法的设计,深入理解进程调度的原理
*
* 实验内容
* 实现短进程优先调度算法(SPF)和时间片轮转调度算法(RR)
*
* 实验要求
* - 进程通过定义一个进程控制块的数据结构(PCB)来表示;
* - 每个进程需要赋予进程ID、进程到达时间、进程需要运行的总时间的属性;
* - 在RR中,以1为时间片单位;
*/

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

#include "OSPPQueue.h"
#include "OSsort.h"

int main()
{
 int i;
 int nProc;
 int tServing, tArriving;

 int nTime = 0;
 int pid = 0;
 int choice;

 PPQueue *qReady = (PPQueue *)malloc(sizeof(PPQueue));
 PPQueue *qFree = (PPQueue *)malloc(sizeof(PPQueue));

 Pcb *data = (Pcb *)malloc(sizeof(Pcb));

 InitGQueues(qReady);
 InitGQueues(qFree);

 printf("Please input the number of processes:  ");
 scanf("%d", &nProc);

 for (i = 0;i < nProc; i++)
 {
  printf("No. %d\n", i);
  printf("\t ServingTime: ");
  scanf("%d", &tServing);
  printf("\t ArrivingTime: ");
  scanf("%d", &tArriving);
  allocPcb(qReady,i,tServing,tArriving);
 }

 do
 {
  printf("Please input the choice[0(RR) | 1(SPF)]: ");
  scanf("%d", &choice);

  if (choice==0)
  {
   while(1)
   {
    printf("nTime = %d\t", nTime++);
    pid = running(qReady, qFree);
    printf("pid = %d\n", pid);
    if (qReady->head==NULL && qReady->tail==NULL)
     break;

   }
  }
  else if (choice == 1)
  {
   /*BubbleSort(qReady);*/
   while(1)
   {
    printf("nTime = %d\t", nTime++);
    pid = invokeSpf(qReady,qFree);
    printf("pid = %d\n", pid);
    if (qReady->head==NULL && qReady->tail==NULL)
     break;
   }
   BubbleSort(qReady);
  }
 } while (choice == 0 && choice == 1);

 freeQueue(qReady);
 freeQueue(qFree);
 qReady = NULL;
 qFree = NULL;

 system("pause");
 return 0;
}