操作系统进程调度算法(c语言模拟实现)

简介: 操作系统进程调度算法(c语言模拟实现)

常见的调度算法

  • 先来先服务调度算法
  • 最短作业优先调度算法
  • 高响应比优先调度算法
  • 最高优先级调度算法
  • 时间片轮转调度算法
  • 多级反馈队列调度算法
  • ... ...

数据结构

typedef struct program
{
  char name[20];
  int running_time;
  int enter_time;
  int priority;
  int done_time;      //用于时间片轮转
  int copyRunning_time;   //用于时间片轮转
  int start_time;
  program* next;
} Program;
typedef struct programQueue
{
  program* firstProg;
  program* LastProg;
  int size;
} programQueue;



先来先服务调度算法

       顾名思义,先来后到,每次从就绪队列选择最先进入队列的进程,然后一直运行,直到进程退出或被阻塞,才会继续从队列中选择第一个进程接着运行。但是当一个长作业先运行了,那么后面的短作业等待的时间就会很长,不利于短作业。FCFS 对长作业有利,适用于 CPU 繁忙型作业的系统,而不适用于 I/O 繁忙型作业的系统。


算法模拟思路:

  • 首先将输入的进程放入一个进程数组中,然后根据进程的到达时间进行排序,将最先到达的进程放入进程就绪队列中。
  • 当队列不空时,从队头取出一个进程来执行,直至此进程执行完,并将在此进程执行期间到达的进程依次加入进程就绪队列。
  • 如果队列为空,但进程数组中仍存在未到达的进程,这时将要到达进程加入进程就绪队列。

算法模拟:

//FCFS先来先服务算法
void FCFS(program pro[], int num)
{
  printf("进程 到达时间  服务时间 开始时间 完成时间 周转时间 带权周转时间\n");
  sortWithEnterTime(pro, num);    //按照进入顺序排序 
  programQueue* queue = (programQueue*)malloc(sizeof(programQueue));
  Queueinit(queue);
  EnterQueue(queue, &pro[0]);
  int time = pro[0].enter_time;
  int pronum = 1;    //记录当前的进程 
  float sum_T_time = 0, sum_QT_time = 0;
  while (queue->size > 0)
  {
    program* curpro = poll(queue);   //从进程队列中取出进程 
    if (time < curpro->enter_time)
      time = curpro->enter_time;
    int done_time = time + curpro->running_time;
    int T_time = done_time - curpro->enter_time;
    sum_T_time += T_time;
    float QT_time = T_time / (curpro->running_time + 0.0);
    sum_QT_time += QT_time;
    for (int tt = time; tt <= done_time && pronum < num; tt++)
    {
      //模拟进程的执行过程 
      if (tt >= pro[pronum].enter_time)
      {
        EnterQueue(queue, &pro[pronum]);
        pronum++;
      }
    }
    printf("%s\t%d\t%d\t%d\t%d\t%d\t%.2f\n", curpro->name, curpro->enter_time, curpro->running_time, time, done_time, T_time, QT_time);
    time += curpro->running_time;
    if (queue->size == 0 && pronum < num)
    {
      //防止出现前一个进程执行完到下一个进程到达之间无进程进入 
      EnterQueue(queue, &pro[pronum]);
      pronum++;
    }
  }
  printf("平均周转时间为%.2f\t平均带权周转时间为%.2f\n", sum_T_time / (num + 0.0), sum_QT_time / (num + 0.0));
}


最短作业优先调度算法

       最短作业优先调度算法会优先选择运行时间最短的进程来运行,这有助于提高系统的吞吐量。这显然对长作业不利,很容易造成一种极端现象。比如,一个长作业在就绪队列等待运行,而这个就绪队列有非常多的短作业,那么就会使得长作业不断的往后推,周转时间变长,致使长作业长期不会被运行。


算法模拟思路:

  1. 首先也是按进程的到达时间进行排序。让最先到达的进程入队。
  2. 当队列不空时,从队头取出一个进程来执行,直至此进程执行完,设置一个变量记录此进程执行过程中所有到达的进程。
  3. 将这些到达的进程进行排序,按照进程服务时间的大小。然后将排序好的进程数组中的进程依次加入进程队列。(只排当前进程执行期间到达的进程)
  4. 此时也要考虑如果队列为空,但进程数组中仍存在未到达的进程,这时将要到达进程加入进程就绪队列。

算法模拟:

//短作业优先算法
void SJF(program pro[], int num)
{
  printf("进程 到达时间  服务时间 开始时间 完成时间 周转时间 带权周转时间\n");
  sortWithEnterTime(pro, num);
  programQueue* queue = (programQueue*)malloc(sizeof(programQueue));
  Queueinit(queue);
  EnterQueue(queue, &pro[0]);
  int time = pro[0].enter_time;
  int pronum = 1;    //记录当前的进程 
  float sum_T_time = 0, sum_QT_time = 0;
  while (queue->size > 0)
  {
    program* curpro = poll(queue);   //从进程队列中取出进程 
    if (time < curpro->enter_time)
      time = curpro->enter_time;
    int done_time = time + curpro->running_time;
    int T_time = done_time - curpro->enter_time;
    float QT_time = T_time / (curpro->running_time + 0.0);
    sum_T_time += T_time;
    sum_QT_time += QT_time;
    int pre = pronum;
    for (int tt = time; tt <= done_time && pronum < num; tt++)
    {
      //模拟进程的执行过程 
      if (tt >= pro[pronum].enter_time)
      {
        // 统计从此任务开始到结束之间有几个进程到达 
        pronum++;
      }
    }
    sortWithLongth(pro, pre, pronum);//将到达的进程按照服务时间排序
    for (int i = pre; i < pronum; i++)
    {
      //将进程链入队列 
      EnterQueue(queue, &pro[i]);
    }
    pre = pronum;
    printf("%s\t%d\t%d\t%d\t%d\t%d\t%.2f\n", curpro->name, curpro->enter_time, curpro->running_time, time, done_time, T_time, QT_time);
    time += curpro->running_time;
    if (queue->size == 0 && pronum < num)
    {
      //防止出现前一个进程执行完到下一个进程到达之间无进程进入 
      EnterQueue(queue, &pro[pronum]);
      pronum++;
    }
  }
  printf("平均周转时间为%.2f\t平均带权周转时间为%.2f\n", sum_T_time / (num + 0.0), sum_QT_time / num);
}


最高优先级调度算法

进程的优先级可以分为,静态优先级或动态优先级:


  • 静态优先级:创建进程时候,就已经确定了优先级了,然后整个运行时间优先级都不会变化;
  • 动态优先级:根据进程的动态变化调整优先级,比如如果进程运行时间增加,则降低其优先级,如果进程等待时间(就绪队列的等待时间)增加,则升高其优先级,也就是随着时间的推移增加等待进程的优先级。

该算法也有两种处理优先级高的方法,非抢占式和抢占式:


  • 非抢占式:当就绪队列中出现优先级高的进程,运行完当前进程,再选择优先级高的进程。
  • 抢占式:当就绪队列中出现优先级高的进程,当前进程挂起,调度优先级高的进程运行。

但是依然有缺点,可能会导致低优先级的进程永远不会运行


算法模拟思路:

  1. 首先也是按进程的到达时间进行排序。让最先到达的进程入队。
  2. 当队列不空时,从队头取出一个进程来执行,直至此进程执行完,设置一个变量记录此进程执行过程中所有到达的进程。
  3. 将这些到达的进程进行排序,按照进程优先权排序(权值小的先入)。然后将排序好的进程数组中的进程依次加入进程队列。(只排当前进程执行期间到达的进程)
  4. 此时也要考虑如果队列为空,但进程数组中仍存在未到达的进程,这时将要到达进程加入进程就绪队列。

算法模拟:

//优先权高者优先(HPF)
void HPF(program pro[], int num)
{
  printf("进程 到达时间  服务时间 开始时间 完成时间 周转时间 带权周转时间\n");
  sortWithEnterTime(pro, num);
  programQueue* queue = (programQueue*)malloc(sizeof(programQueue));
  Queueinit(queue);
  EnterQueue(queue, &pro[0]);
  int time = pro[0].enter_time;
  int pronum = 1;    //记录当前的进程 
  float sum_T_time = 0, sum_QT_time = 0;
  while (queue->size > 0)
  {
    program* curpro = poll(queue);   //从进程队列中取出进程 
    if (time < curpro->enter_time)
      time = curpro->enter_time;
    int done_time = time + curpro->running_time;
    int T_time = done_time - curpro->enter_time;
    float QT_time = T_time / (curpro->running_time + 0.0);
    sum_T_time += T_time;
    sum_QT_time += QT_time;
    int pre = pronum;
    for (int tt = time; tt <= done_time && pronum < num; tt++)
    {
      //模拟进程的执行过程 
      if (tt >= pro[pronum].enter_time)
      {
        // 统计从此任务开始到结束之间有几个进程到达 
        pronum++;
      }
    }
    sortWithPriority(pro, pre, pronum);//将到达的进程按照服务时间排序
    for (int i = pre; i < pronum; i++)
    {
      //将进程链入队列 
      EnterQueue(queue, &pro[i]);
    }
    pre = pronum;
    printf("%s\t%d\t%d\t%d\t%d\t%d\t%.2f\n", curpro->name, curpro->enter_time, curpro->running_time, time, done_time, T_time, QT_time);
    time += curpro->running_time;
    if (queue->size == 0 && pronum < num)
    {
      //防止出现前一个进程执行完到下一个进程到达之间无进程进入 
      EnterQueue(queue, &pro[pronum]);
      pronum++;
    }
  }
  printf("平均周转时间为%.2f\t平均带权周转时间为%.2f\n", sum_T_time / (num + 0.0), sum_QT_time / (num + 0.0));
}



时间片轮转调度算法

       每个进程被分配一个时间段,称为时间片,即允许该进程在该时间段中运行。如果时间片用完,进程还在运行,那么将会把此进程从 CPU 释放出来,并把 CPU 分配另外一个进程;如果该进程在时间片结束前阻塞或结束,则 CPU 立即进行切换;如果时间片设得太短会导致过多的进程上下文切换,降低了 CPU 效率;如果设得太长又可能引起对短作业进程的响应时间变长。


算法模拟思路:

  1. 首先也是按进程的到达时间进行排序。让最先到达的进程入队。
  2. 当队列不空时,从队头取出一个进程来执行。此时分两种情况:①如果当前进程的剩余服务时间不大于时间片大小,说明此次将会将这个进程执 行完毕,在此进程执行过程中到达的进程需要添加到进程就绪队列中,这时就可以输出 此进程执行完毕②如果当前进程的剩余服务时间大于时间片大小,还需将此进程执行过程中到达 的进程需要添加到进程就绪队列中,然后此进程的剩余服务时间减少时间片大小,此进 程重新进入进程就绪队列
  3. 此时也要考虑如果队列为空,但进程数组中仍存在未到达的进程,这时将要到达进程加入进程就绪队列

算法模拟:

//时间片轮转(RR)
void RR(program pro[], int num)
{
  printf("请输入时间片大小");
  int timeslice; scanf("%d", &timeslice);
  printf("进程 到达时间  服务时间 进入时间 完成时间 周转时间 带权周转时间\n");
  sortWithEnterTime(pro, num);
  programQueue* queue = (programQueue*)malloc(sizeof(programQueue));
  Queueinit(queue);
  pro[0].start_time = pro[0].enter_time;
  EnterQueue(queue, &pro[0]);
  int time = 0;
  int pronum = 1;
  float sum_T_time = 0, sum_QT_time = 0;
  while (queue->size > 0)
  {
    program* curpro = poll(queue);    // 从队列中取出头节点 
    if (time < curpro->enter_time)
      time = curpro->enter_time;
    if (timeslice >= curpro->running_time)
    {
      // 如果剩余时间小于时间片  则此任务完成
      for (int tt = time; tt <= time + curpro->running_time && pronum < num; tt++)
      {
        // 模拟进程的执行过程 
        if (tt >= pro[pronum].enter_time)
        {
          // 统计从此任务开始到结束之间有几个进程到达 
          pro[pronum].start_time = tt;
          EnterQueue(queue, &pro[pronum]);
          pronum++;
        }
      }
      time += curpro->running_time;
      curpro->running_time = 0;
      curpro->done_time = time;
      int T_time = curpro->done_time - curpro->start_time;
      float QT_time = T_time / (curpro->copyRunning_time + 0.0);
      sum_T_time += T_time;
      sum_QT_time += QT_time;
      printf("%s\t%d\t%d\t  %d\t   %d\t %d\t  %.2f\n", curpro->name, curpro->enter_time, curpro->copyRunning_time,
        curpro->start_time, curpro->done_time, T_time, QT_time);
      if (queue->size == 0 && pronum < num)
      {
        //防止出现前一个进程执行完到下一个进程到达之间无进程进入 
        pro[pronum].start_time = pro[pronum].enter_time;
        EnterQueue(queue, &pro[pronum]);
        pronum++;
      }
      continue;
    }
    for (int tt = time; tt <= time + timeslice && pronum < num; tt++)
    {
      //模拟进程的执行过程 
      if (tt >= pro[pronum].enter_time)
      {
        // 统计从此任务开始到结束之间有几个进程到达 
        pro[pronum].start_time = tt;
        EnterQueue(queue, &pro[pronum]);
        pronum++;
      }
    }
    time += timeslice;
    curpro->running_time -= timeslice;
    EnterQueue(queue, curpro);    //当前程序未完成  继续添加到队列中 
    if (queue->size == 0 && pronum < num)
    {
      //防止出现前一个进程执行完到下一个进程到达之间无进程进入 
      pro[pronum].start_time = pro[pronum].enter_time;
      EnterQueue(queue, &pro[pronum]);
      pronum++;
    }
  }
  printf("平均周转时间为%.2f\t平均带权周转时间为%.2f\n\n", sum_T_time / (num + 0.0), sum_QT_time / (num + 0.0));
}


完整代码:

我们分三个文件进行操作,当然大家也可以把三个文件按顺序放在一个文件里面进行操作


course.h:      结构体的包含以及函数的声明


course.cpp:  函数的具体实现


test.cpp:       主函数用于调用其余文件函数



course.h:

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<malloc.h>
#include<string.h> 
#include<stdlib.h>
typedef struct program
{
  char name[20];
  int running_time;
  int enter_time;
  int priority;
  int done_time;      //用于时间片轮转
  int copyRunning_time;   //用于时间片轮转
  int start_time;
  program* next;
} Program;
typedef struct programQueue
{
  program* firstProg;
  program* LastProg;
  int size;
} programQueue;
//初始化
void Queueinit(programQueue* queue);
//打印
void print(program pro[], int num);
//打印队列
void printQueue(programQueue* queue);
//加入进程队列 
void EnterQueue(programQueue* queue, program* pro);
//查询
program* poll(programQueue* queue);
//输入
void inputProgram(program pro[], int num);
//根据时间排序
void sortWithEnterTime(program pro[], int num);
//FCFS先来先服务算法
void FCFS(program pro[], int num);
//根据长度排序
void sortWithLongth(program pro[], int start, int end);
//短作业优先算法
void SJF(program pro[], int num);
//根据优先级排列
void sortWithPriority(program pro[], int start, int end);
//优先权高者优先(HPF)
void HPF(program pro[], int num);
//时间片轮转(RR)
void RR(program pro[], int num);
//选择菜单
void choiceMenu();


course.cpp:

#define _CRT_SECURE_NO_WARNINGS 1
#include "course.h"
//初始化
void Queueinit(programQueue* queue)
{
  if (queue == NULL)
  {
    return;
  }
  queue->size = 0;
  queue->LastProg = (program*)malloc(sizeof(program));
  queue->firstProg = queue->LastProg;
}
//打印
void print(program pro[], int num)
{
  for (int i = 0; i < num; i++)
  {
    printf("%d ", pro[i].enter_time);
  }
}
//打印输出队列
void printQueue(programQueue* queue)
{
  program* p = queue->firstProg->next;
  while (p != NULL)
  {
    printf("%s ", p->name);
    p = p->next;
  }
  printf("\n");
}
//加入进程队列 
void EnterQueue(programQueue* queue, program* pro)
{
  queue->LastProg->next = (program*)malloc(sizeof(program));
  queue->LastProg = queue->LastProg->next;
  queue->LastProg->enter_time = pro->enter_time;
  memcpy(queue->LastProg->name, pro->name, sizeof(pro->name));
  queue->LastProg->priority = pro->priority;
  queue->LastProg->running_time = pro->running_time;
  queue->LastProg->copyRunning_time = pro->copyRunning_time;
  queue->LastProg->start_time = pro->start_time;
  queue->size++;
}
//查询
program* poll(programQueue* queue)
{
  program* temp = queue->firstProg->next;
  if (temp == queue->LastProg)
  {
    queue->LastProg = queue->firstProg;
    queue->size--;
    return temp;
  }
  queue->firstProg->next = queue->firstProg->next->next;
  queue->size--;
  return temp;
}
//输入
void inputProgram(program pro[], int num)
{
  for (int i = 0; i < num; i++)
  {
    program prog;
    printf("请输入第%d个进程的名字,到达时间,服务时间,优先级\n", i + 1);
    scanf("%s", prog.name);
    scanf("%d", &prog.enter_time);
    scanf("%d", &prog.running_time);
    prog.copyRunning_time = prog.running_time;
    scanf("%d", &prog.priority);
    pro[i] = prog;
  }
}
//根据时间排序
void sortWithEnterTime(program pro[], int num)
{
  for (int i = 1; i < num; i++)
  {
    for (int j = 0; j < num - i; j++)
    {
      if (pro[j].enter_time > pro[j + 1].enter_time)
      {
        program temp = pro[j];
        pro[j] = pro[j + 1];
        pro[j + 1] = temp;
      }
    }
  }
}
//FCFS先来先服务算法
void FCFS(program pro[], int num)
{
  printf("进程 到达时间  服务时间 开始时间 完成时间 周转时间 带权周转时间\n");
  sortWithEnterTime(pro, num);    //按照进入顺序排序 
  programQueue* queue = (programQueue*)malloc(sizeof(programQueue));
  Queueinit(queue);
  EnterQueue(queue, &pro[0]);
  int time = pro[0].enter_time;
  int pronum = 1;    //记录当前的进程 
  float sum_T_time = 0, sum_QT_time = 0;
  while (queue->size > 0)
  {
    program* curpro = poll(queue);   //从进程队列中取出进程 
    if (time < curpro->enter_time)
      time = curpro->enter_time;
    int done_time = time + curpro->running_time;
    int T_time = done_time - curpro->enter_time;
    sum_T_time += T_time;
    float QT_time = T_time / (curpro->running_time + 0.0);
    sum_QT_time += QT_time;
    for (int tt = time; tt <= done_time && pronum < num; tt++)
    {
      //模拟进程的执行过程 
      if (tt >= pro[pronum].enter_time)
      {
        EnterQueue(queue, &pro[pronum]);
        pronum++;
      }
    }
    printf("%s\t%d\t%d\t%d\t%d\t%d\t%.2f\n", curpro->name, curpro->enter_time, curpro->running_time, time, done_time, T_time, QT_time);
    time += curpro->running_time;
    if (queue->size == 0 && pronum < num)
    {
      //防止出现前一个进程执行完到下一个进程到达之间无进程进入 
      EnterQueue(queue, &pro[pronum]);
      pronum++;
    }
  }
  printf("平均周转时间为%.2f\t平均带权周转时间为%.2f\n", sum_T_time / (num + 0.0), sum_QT_time / (num + 0.0));
}
//根据长度排序
void sortWithLongth(program pro[], int start, int end)
{
  int len = end - start;
  if (len == 1) return;
  for (int i = 1; i < len; i++) {
    for (int j = start; j < end - i; j++)
    {
      if (pro[j].running_time > pro[j + 1].running_time)
      {
        program temp = pro[j];
        pro[j] = pro[j + 1];
        pro[j + 1] = temp;
      }
    }
  }
}
//短作业优先算法
void SJF(program pro[], int num)
{
  printf("进程 到达时间  服务时间 开始时间 完成时间 周转时间 带权周转时间\n");
  sortWithEnterTime(pro, num);
  programQueue* queue = (programQueue*)malloc(sizeof(programQueue));
  Queueinit(queue);
  EnterQueue(queue, &pro[0]);
  int time = pro[0].enter_time;
  int pronum = 1;    //记录当前的进程 
  float sum_T_time = 0, sum_QT_time = 0;
  while (queue->size > 0)
  {
    program* curpro = poll(queue);   //从进程队列中取出进程 
    if (time < curpro->enter_time)
      time = curpro->enter_time;
    int done_time = time + curpro->running_time;
    int T_time = done_time - curpro->enter_time;
    float QT_time = T_time / (curpro->running_time + 0.0);
    sum_T_time += T_time;
    sum_QT_time += QT_time;
    int pre = pronum;
    for (int tt = time; tt <= done_time && pronum < num; tt++)
    {
      //模拟进程的执行过程 
      if (tt >= pro[pronum].enter_time)
      {
        // 统计从此任务开始到结束之间有几个进程到达 
        pronum++;
      }
    }
    sortWithLongth(pro, pre, pronum);//将到达的进程按照服务时间排序
    for (int i = pre; i < pronum; i++)
    {
      //将进程链入队列 
      EnterQueue(queue, &pro[i]);
    }
    pre = pronum;
    printf("%s\t%d\t%d\t%d\t%d\t%d\t%.2f\n", curpro->name, curpro->enter_time, curpro->running_time, time, done_time, T_time, QT_time);
    time += curpro->running_time;
    if (queue->size == 0 && pronum < num)
    {
      //防止出现前一个进程执行完到下一个进程到达之间无进程进入 
      EnterQueue(queue, &pro[pronum]);
      pronum++;
    }
  }
  printf("平均周转时间为%.2f\t平均带权周转时间为%.2f\n", sum_T_time / (num + 0.0), sum_QT_time / num);
}
//根据优先级排列
void sortWithPriority(program pro[], int start, int end)
{
  int len = end - start;
  if (len == 1) return;
  for (int i = 1; i < len; i++)
  {
    for (int j = start; j < end - i; j++)
    {
      if (pro[j].priority > pro[j + 1].priority)
      {
        program temp = pro[j];
        pro[j] = pro[j + 1];
        pro[j + 1] = temp;
      }
    }
  }
}
//优先权高者优先(HPF)
void HPF(program pro[], int num)
{
  printf("进程 到达时间  服务时间 开始时间 完成时间 周转时间 带权周转时间\n");
  sortWithEnterTime(pro, num);
  programQueue* queue = (programQueue*)malloc(sizeof(programQueue));
  Queueinit(queue);
  EnterQueue(queue, &pro[0]);
  int time = pro[0].enter_time;
  int pronum = 1;    //记录当前的进程 
  float sum_T_time = 0, sum_QT_time = 0;
  while (queue->size > 0)
  {
    program* curpro = poll(queue);   //从进程队列中取出进程 
    if (time < curpro->enter_time)
      time = curpro->enter_time;
    int done_time = time + curpro->running_time;
    int T_time = done_time - curpro->enter_time;
    float QT_time = T_time / (curpro->running_time + 0.0);
    sum_T_time += T_time;
    sum_QT_time += QT_time;
    int pre = pronum;
    for (int tt = time; tt <= done_time && pronum < num; tt++)
    {
      //模拟进程的执行过程 
      if (tt >= pro[pronum].enter_time)
      {
        // 统计从此任务开始到结束之间有几个进程到达 
        pronum++;
      }
    }
    sortWithPriority(pro, pre, pronum);//将到达的进程按照服务时间排序
    for (int i = pre; i < pronum; i++)
    {
      //将进程链入队列 
      EnterQueue(queue, &pro[i]);
    }
    pre = pronum;
    printf("%s\t%d\t%d\t%d\t%d\t%d\t%.2f\n", curpro->name, curpro->enter_time, curpro->running_time, time, done_time, T_time, QT_time);
    time += curpro->running_time;
    if (queue->size == 0 && pronum < num)
    {
      //防止出现前一个进程执行完到下一个进程到达之间无进程进入 
      EnterQueue(queue, &pro[pronum]);
      pronum++;
    }
  }
  printf("平均周转时间为%.2f\t平均带权周转时间为%.2f\n", sum_T_time / (num + 0.0), sum_QT_time / (num + 0.0));
}
//时间片轮转(RR)
void RR(program pro[], int num)
{
  printf("请输入时间片大小");
  int timeslice; scanf("%d", &timeslice);
  printf("进程 到达时间  服务时间 进入时间 完成时间 周转时间 带权周转时间\n");
  sortWithEnterTime(pro, num);
  programQueue* queue = (programQueue*)malloc(sizeof(programQueue));
  Queueinit(queue);
  pro[0].start_time = pro[0].enter_time;
  EnterQueue(queue, &pro[0]);
  int time = 0;
  int pronum = 1;
  float sum_T_time = 0, sum_QT_time = 0;
  while (queue->size > 0)
  {
    program* curpro = poll(queue);    // 从队列中取出头节点 
    if (time < curpro->enter_time)
      time = curpro->enter_time;
    if (timeslice >= curpro->running_time)
    {
      // 如果剩余时间小于时间片  则此任务完成
      for (int tt = time; tt <= time + curpro->running_time && pronum < num; tt++)
      {
        // 模拟进程的执行过程 
        if (tt >= pro[pronum].enter_time)
        {
          // 统计从此任务开始到结束之间有几个进程到达 
          pro[pronum].start_time = tt;
          EnterQueue(queue, &pro[pronum]);
          pronum++;
        }
      }
      time += curpro->running_time;
      curpro->running_time = 0;
      curpro->done_time = time;
      int T_time = curpro->done_time - curpro->start_time;
      float QT_time = T_time / (curpro->copyRunning_time + 0.0);
      sum_T_time += T_time;
      sum_QT_time += QT_time;
      printf("%s\t%d\t%d\t  %d\t   %d\t %d\t  %.2f\n", curpro->name, curpro->enter_time, curpro->copyRunning_time,
        curpro->start_time, curpro->done_time, T_time, QT_time);
      if (queue->size == 0 && pronum < num)
      {
        //防止出现前一个进程执行完到下一个进程到达之间无进程进入 
        pro[pronum].start_time = pro[pronum].enter_time;
        EnterQueue(queue, &pro[pronum]);
        pronum++;
      }
      continue;
    }
    for (int tt = time; tt <= time + timeslice && pronum < num; tt++)
    {
      //模拟进程的执行过程 
      if (tt >= pro[pronum].enter_time)
      {
        // 统计从此任务开始到结束之间有几个进程到达 
        pro[pronum].start_time = tt;
        EnterQueue(queue, &pro[pronum]);
        pronum++;
      }
    }
    time += timeslice;
    curpro->running_time -= timeslice;
    EnterQueue(queue, curpro);    //当前程序未完成  继续添加到队列中 
    if (queue->size == 0 && pronum < num)
    {
      //防止出现前一个进程执行完到下一个进程到达之间无进程进入 
      pro[pronum].start_time = pro[pronum].enter_time;
      EnterQueue(queue, &pro[pronum]);
      pronum++;
    }
  }
  printf("平均周转时间为%.2f\t平均带权周转时间为%.2f\n\n", sum_T_time / (num + 0.0), sum_QT_time / (num + 0.0));
}
//选择菜单
void choiceMenu()
{
  printf("请选择进程调度算法:\n");
  printf("1.先来先服务算法\n");
  printf("2.短进程优先算法\n");
  printf("3.高优先级优先\n");
  printf("4.时间片轮转算法\n");
}

test.cpp

#define _CRT_SECURE_NO_WARNINGS 1
#include"course.h"
int main()
{
  int proNum = 5;   //5个进程
  program pro[5];
  inputProgram(pro, proNum);
  choiceMenu();
  int choice;
  do
  {
    scanf("%d", &choice);
    switch (choice)
    {
    case 1:
      system("cls");
      FCFS(pro, proNum);
      choiceMenu();
      break;
    case 2:
      system("cls");
      SJF(pro, proNum);
      choiceMenu();
      break;
    case 3:
      system("cls");
      HPF(pro, proNum);
      choiceMenu();
      break;
    case 4:
      system("cls");
      RR(pro, proNum);
      choiceMenu();
      break;
    default:
      printf("输入错误,请重新尝试\n");
      break;
    }
  } while (choice);
  return 0;
}
目录
相关文章
|
1天前
|
消息中间件 算法 安全
深入理解操作系统:进程管理的艺术
【8月更文挑战第30天】在数字世界的舞台上,操作系统(OS)扮演着导演的角色,精心编排着每一个进程的演出。本文将揭开进程管理的神秘面纱,通过浅显的语言和生动的比喻,带你领略进程调度、同步与通信等背后的技术魔法。就像甘地所言:“你必须成为你希望在世界上看到的改变。”了解并掌握进程管理,你将能够更好地驾驭这个数字世界的复杂性,成为技术变革的先行者。
|
1天前
|
监控 算法 调度
探索操作系统中的进程管理:从理论到实践
【8月更文挑战第30天】在数字世界的心脏,操作系统扮演着至关重要的角色。它不仅管理着硬件资源,还确保了软件的顺畅运行。本文将深入探讨操作系统中的一项核心功能——进程管理。我们将从基本概念出发,逐步深入到进程状态、调度算法,以及进程同步机制。通过实际代码示例,我们将看到理论如何转化为实践中的具体操作,从而更好地理解进程管理的精妙之处。无论你是初学者还是有一定基础的开发者,这篇文章都将为你揭开操作系统进程管理的神秘面纱。
|
1天前
|
算法 安全 网络安全
探索操作系统核心:进程调度的奥秘网络安全的盾牌与剑——漏洞防御与加密技术
【8月更文挑战第30天】在数字世界的每一次点击和命令背后,都隐藏着一个不为人知的英雄——进程调度器。它默默无闻地在后台工作,确保我们的命令得以流畅执行。本文将揭开这位幕后英雄的面纱,带你了解进程调度的原理、重要性以及它是如何在操作系统中发挥作用的。无论你是编程新手还是资深开发者,理解进程调度都能帮你更好地掌握计算机的运作原理。准备好深入操作系统的核心,一探究竟了吗?让我们开始吧!
|
1天前
|
消息中间件 算法 Java
深入浅出操作系统:进程管理的艺术掌握Java中的异常处理机制
【8月更文挑战第30天】在数字世界的舞台上,操作系统扮演着导演的角色,精心安排着每一个进程的表演。本文将揭开进程管理的神秘面纱,从进程的诞生到终结,探究它们如何在操作系统的指挥下和谐共舞。通过生动的比喻和直观的代码示例,我们将一同走进操作系统的核心,理解进程调度、同步与通信的内在机制,以及它们对计算生态的重要性。让我们跟随代码的节奏,一起感受操作系统的魅力吧!
|
1天前
|
算法 调度 开发者
深入理解操作系统:进程管理与调度
【8月更文挑战第30天】本文将带你进入操作系统的核心世界,探索进程管理的奥秘和进程调度的策略。我们将通过直观的例子和代码片段,揭示操作系统如何有效管理计算资源,确保系统稳定运行和高性能。你将了解进程状态的变迁、调度算法的原理以及如何在实际编程中利用这些知识。无论你是操作系统的学习者还是软件开发的实践者,这篇文章都将为你提供宝贵的洞见。
|
2天前
|
调度
深入理解操作系统:进程与线程的管理
【8月更文挑战第29天】在数字世界的每一次点击和滑动背后,都隐藏着操作系统的精妙运作。本文将带你探索操作系统的核心概念之一——进程与线程的管理。我们将从基础定义出发,逐步深入到它们在内存中的表示、状态变迁以及它们之间错综复杂的关系。通过简洁明了的语言和直观的比喻,即便是没有计算机背景的读者也能轻松理解这一主题。准备好了吗?让我们一起揭开操作系统神秘的面纱,探索那些看似晦涩却无比精彩的知识吧!
|
1天前
|
算法 Unix 程序员
深入浅出操作系统的进程管理
【8月更文挑战第30天】在数字世界的心脏跳动着无数个进程,它们如同细胞一般构成了操作系统的生命体。本文将带你领略进程管理的奥秘,从进程的诞生到成长,再到它们的衰老和死亡,我们将一起探索如何通过有效的进程管理来优化系统性能和用户体验。你将学习到进程调度、同步与通信等核心概念,并了解如何在实际编程中应用这些知识。让我们一起开启这场操作系统的深度之旅,发现那些隐藏在日常电脑使用背后的神奇魔法。
|
1天前
|
Linux 调度 开发者
探索操作系统核心:进程与线程的管理
【8月更文挑战第30天】在数字世界的心脏,操作系统扮演着至关重要的角色。它不仅是计算机硬件与软件之间的桥梁,更是管理和调度计算资源的核心。本文将深入探讨操作系统中最为关键的两个概念:进程与线程。我们将从基本的定义出发,逐步揭示它们之间的区别、联系以及如何在操作系统中高效管理这些基础单位。通过实际代码示例,我们将进一步理解操作系统如何精确控制和优化进程与线程的运行,确保系统的稳定与高效。无论你是软件开发者还是系统管理员,这篇文章都将为你打开一扇了解操作系统深层工作机制的大门。
|
2天前
|
算法 调度 UED
深入理解操作系统中的进程调度
【8月更文挑战第29天】本文旨在通过浅显易懂的语言,向读者揭示操作系统中一个核心概念——进程调度的奥秘。我们将从基础概念出发,逐步深入到进程调度的策略和算法,最后探讨其对系统性能的影响。无论你是初学者还是有一定基础的技术人员,都能在这篇文章中找到有价值的信息。
|
2天前
|
UED Python
深入理解操作系统:进程与线程的管理
【8月更文挑战第29天】本文将通过浅显的语言和生动的比喻,带你走进操作系统的核心世界,探索进程与线程的秘密。我们将从基础概念出发,逐步深入到它们在操作系统中的管理方式,以及如何影响计算机的性能和稳定性。文章旨在启发读者思考操作系统设计的哲学,同时提供实用的知识,帮助理解现代计算机系统的运作原理。
下一篇
云函数