进程调度算法(优先数法和简单轮转法)C/C++

一、算法描述
用优先数调度算法或简单轮转法对五个进程进行调度,每个进程处于运行(Run)、就绪(Ready)和完成(Finish)三种状态之一,并假定起始状态为就绪状态。

二、进程控制块结构
这里写图片描述

进程控制块的链结构
这里写图片描述
其中:Run——表是当前运行进程指针
Ready——就绪队列头指针
Tail——就绪队列尾指针
Finish——完成队列指针

三、算法说明及程序框图
(1) 为了便于处理,程序中进程的运行时间以时间片为单位进行计算,各进程的优先数或轮转时间片数,以及进程需要运行的时间片数,其初始值均有用户给定。
(2) 优先数法
进程就绪队列按优先数大小从高到低排列,链首进程首先投入运行。进程每执行一次,进程需要的时间片数减1、该进程的优先数减3。这样,该进程如果在一个时间片中没有完成,其优先数降低一级。接着仍是用该进程降低一级后的优先数与就绪队列中链首进程的优先数进行比较,如果仍是该进程的优先数高或相同,便让该进程继续执行;否则,调度就绪队列的链首进程投入运行。原运行过的进程按其现行优先数大小插入就绪队列,且改变它们对应的进程状态,一直到所有进程都运行完各自的时间片数。
(3) 简单轮转法
进程就绪队列按各进程进入的先后顺序排列。进程每次所需处理机的轮转式按其重要程度记入进程控制块中的轮转时间片数记录项。进程执行时,每运行一个时间片,进程还需要的时间片数减1,运行进程占用处理机的时间片数加1,然后比较占用CPU的时间片数是否与该进程的轮转时间片数相等,若相等则说明已达到轮转时间,应将现运行的进程排列就绪队列的末尾,调度队列上的首进程运行,且改变它们的进程状态,直至所有进程完成各自的时间片。
(4) 程序框图
这里写图片描述

这里写图片描述

四、算法实现
1、优先数调度算法

/*
 *利用C/C++模拟进程调度,运用优先调度算法
 */
#include<iostream>
#include<stdio.h>
#include<malloc.h>
using namespace std;
enum process_status{READY , RUN , FINISH}; //进程的三种状态
//定义进程数据结构
typedef struct pcb
{
    char process_tag[20] ; //存储进程标识符
    struct pcb *next ; //连接下一个进程的指针
    int priority_num ; //优先调度算法中为优先级 , 轮转调度算法中为轮转时间片
    int take_cpu_time ; //占用CPU时间片数
    int process_time ; //进程所需时间片数
    process_status status ; //进程当前的状态
} PCB ;
//定义进程控制块的链结构
typedef struct
{
    PCB *run ; //当前运行的进程指针
    PCB *ready ; //当前准备队列的头指针
    PCB *tail ; //准备队列的队尾指针
    PCB *finish ; //完成队列的指针
} PCBC ;
void init_pcbc(PCBC *p)
{
    p->run = NULL ;
    p->ready = NULL ;
    p->tail = NULL ;
    p->finish = NULL ;
}
//输入进程,并加入就绪队列
void input_process(PCBC *pcbc)
{
   PCB *pcb ;
   pcb = (PCB*)malloc(sizeof(PCB)) ;
   printf("请输入进程标识符:") ;
   scanf("%s" , &pcb->process_tag) ;
   printf("输入格式为: (优先级,占用CPU时间片数,进程所需时间片数) : ") ;
   scanf("%d,%d,%d" , &pcb->priority_num , &pcb->take_cpu_time , &pcb->process_time) ;
   pcb->status = READY ; //初始化就绪状态
   //当就绪队列为空时
   if(pcbc->ready == NULL && pcbc->tail == NULL)
   {
       pcbc->ready = pcbc->tail = pcb ;
       pcb->next = NULL ;
   }
   else
   {
       //将新进入的队列加入队尾
       pcb->next = pcbc->tail->next ;
       pcbc->tail->next = pcb ;
       pcbc->tail = pcb ;
   }
}
void swapx(PCB  * p1 , PCB *p2)
{
    int  i , priority_num , take_cpu_time , process_time ;
    char temp ;
    //进行标识符的交换
    for(i = 0 ; i < 20 ; i++)
    {
        temp = p1->process_tag[i];
        p1->process_tag[i] = p2->process_tag[i] ;
        p2->process_tag[i] = temp ;
    }
    //优先值的交换
    priority_num = p1->priority_num ;
    p1->priority_num = p2->priority_num ;
    p2->priority_num = priority_num ;
    //占用CPU时间片的交换
    take_cpu_time = p1->take_cpu_time ;
    p1->take_cpu_time = p2->take_cpu_time ;
    p2->take_cpu_time = take_cpu_time ;
    //进程所需时间片数的交换
    process_time = p1->process_time ;
    p1->process_time = p2->process_time ;
    p2->process_time = process_time ;
}
//将就绪队列按优先级别大小进行排序,按冒泡排序算法
void sort_pcbc(PCBC *pcbc , int pcb_num)
{
    PCB *p  , *p1 ;
    p = pcbc->ready ;
   for(p = pcbc->ready ; p != NULL ; p = p->next)
   {
       for(p1 = p->next ; p1 != NULL ; p1 = p1->next)
       {
           if(p->priority_num < p1->priority_num)
           {
               swapx(p , p1) ; //只是进行指针内部数据的交换,不改变指针指向
           }
       }
   }
}
/*
 *打印当前进程控制块中的情况
 */
 void print_log(PCBC *pcbc)
 {
     PCB *ready , *finish ;
     ready = pcbc->ready ;
     finish = pcbc->finish ;
     printf("--------------------------------------------------  \n") ;
     printf("Run: \n") ;
     if(pcbc->run != NULL)
     {
        printf("%s  %04d  %04d  %04d \n" , pcbc->run->process_tag ,pcbc->run->priority_num , pcbc->run->take_cpu_time , pcbc->run->process_time) ;
     }
     else
     {
         printf("Run is empty! \n") ;
     }
     printf("Ready:\n") ;
     while(ready != NULL)
     {
         printf("%s  %04d  %04d  %04d \n" , ready->process_tag ,ready->priority_num , ready->take_cpu_time , ready->process_time) ;
         ready = ready->next ;
     }
     printf("Finish:\n") ;
     while(finish != NULL)
     {
         printf("%s  %04d  %04d  %04d \n" , finish->process_tag ,finish->priority_num , finish->take_cpu_time , finish->process_time) ;
         finish = finish->next ;
     }
 }
/*
 *运行进程控制块
 */
 void run_pcbc_priority(PCBC *xpcbc)
 {
     PCBC *pcbc = xpcbc ;
     PCB *temp , *pre , *tail ;
     //进行那个CPU的循环调用
     while(pcbc->ready != NULL)
     {
         pcbc->run = pcbc->ready ; //将就绪队列队首加入运行队列
         pcbc->ready = pcbc->ready->next ; //改变队首元素
         print_log(pcbc) ;
         pcbc->run->priority_num -= 3 ;
         pcbc->run->process_time -= 1 ;
         if(pcbc->run->process_time == 0)
         {
           if(pcbc->finish == NULL)
           {
               pcbc->finish = pcbc->run ;
               pcbc->finish->next = NULL ;
               tail = pcbc->finish ;
           }
           else
           {
              tail->next = pcbc->run ;
              tail = tail->next ;
              tail->next = NULL ;
           }
         }
         else
         {
             if(pcbc->ready != NULL)
             {
                 temp = pcbc->ready ;
                 while(temp != NULL)
                 {
                     if(pcbc->run->priority_num > temp->priority_num)
                     {
                         break ;
                     }
                     pre = temp ;
                     temp = temp->next ;
                 }
                 if(temp == pcbc->ready)
                 {
                     pcbc->run->next = pcbc->ready ;
                     pcbc->ready = pcbc->run ;
                 }
                 else
                 {
                    pcbc->run->next = pre->next ;
                    pre->next = pcbc->run ;
                 }
             }
             else
             {
                 pcbc->ready = pcbc->run ;
             }
         }
     }
     pcbc->run = NULL ;
     print_log(pcbc) ;
 }
int main()
{
    PCBC *pcbc ; //创建进程控制块链 ;
    int pcb_num ; //记录处理进程数目
    pcbc = (PCBC*)malloc(sizeof(PCBC)) ;
    printf("请输入要处理的进程数目: ") ;
    scanf("%d" , &pcb_num) ;
    init_pcbc(pcbc) ; //初始化进程控制块链
    for(int i = 0 ; i < pcb_num ; i++)
    {
        input_process(pcbc) ; //输入所有进程,并进入就绪队列
    }
    //根据队列优先级进行排序
    sort_pcbc(pcbc , pcb_num) ;
    //通过优先调度算法运行
    printf("By the priority--------------------------\n") ;
    run_pcbc_priority(pcbc) ;
    return 0 ;
}

2、简单轮转时间片调度算法

/*
 *利用C/C++模拟进程调度,运用轮转时间片调度算法
 */
#include<stdio.h>
#include<malloc.h>
enum process_status{READY , RUN , FINISH}; //进程的三种状态
//定义进程数据结构
typedef struct pcb
{
    char process_tag[20] ; //存储进程标识符
    struct pcb *next ; //连接下一个进程的指针
    int time_slice ; // 轮转调度算法中为轮转时间片
    int take_cpu_time ; //占用CPU时间片数
    int process_time ; //进程所需时间片数
    process_status status ; //进程当d前的状态
} PCB ;
//定义进程控制块的链结构
typedef struct
{
    PCB *run ; //当前运行的进程指针
    PCB *ready ; //当前准备队列的头指针
    PCB *tail ; //准备队列的队尾指针
    PCB *finish ; //完成队列的指针
} PCBC ;
void init_pcbc(PCBC *p)
{
    p->run = NULL ;
    p->ready = NULL ;
    p->tail = NULL ;
    p->finish = NULL ;
}
//输入进程,并加入就绪队列
void input_process(PCBC *pcbc)
{
   PCB *pcb ;
   pcb = (PCB*)malloc(sizeof(PCB)) ;
   printf("请输入进程标识符:") ;
   scanf("%s" , &pcb->process_tag) ;
   printf("输入格式为: (优先级,占用CPU时间片数,进程所需时间片数) : ") ;
   scanf("%d,%d,%d" , &pcb->time_slice , &pcb->take_cpu_time , &pcb->process_time) ;
   pcb->status = READY ; //初始化就绪状态
   //当就绪队列为空时
   if(pcbc->ready == NULL && pcbc->tail == NULL)
   {
       pcbc->ready = pcbc->tail = pcb ;
       pcb->next = NULL ;
   }
   else
   {
       //将新进入的元素加入队尾
       pcb->next = pcbc->tail->next ;
       pcbc->tail->next = pcb ;
       pcbc->tail = pcb ;
   }
}
/*
 *打印当前进程控制块中的情况
 */
 void print_log(PCBC *pcbc)
 {
     PCB *ready , *finish ;
     ready = pcbc->ready ;
     finish = pcbc->finish ;
     printf("--------------------------------------------------  \n") ;
     printf("Run: \n") ;
     if(pcbc->run != NULL)
     {
        printf("%s  %04d  %04d  %04d \n" , pcbc->run->process_tag ,pcbc->run->time_slice , pcbc->run->take_cpu_time , pcbc->run->process_time) ;
     }
     else
     {
         printf("Run is empty! \n") ;
     }
     printf("Ready:\n") ;
     while(ready != NULL)
     {
         printf("%s  %04d  %04d  %04d \n" , ready->process_tag ,ready->time_slice , ready->take_cpu_time , ready->process_time) ;
         ready = ready->next ;
     }
     printf("Finish:\n") ;
     while(finish != NULL)
     {
         printf("%s  %04d  %04d  %04d \n" , finish->process_tag ,finish->time_slice , finish->take_cpu_time , finish->process_time) ;
         finish = finish->next ;
     }
 }
 /*
  *通过轮转时间片调度算法
  */
void run_pcbc_timeSlice(PCBC *xpcbc)
{
      PCBC *pcbc = xpcbc ;
      PCB *temp , *pre , *tail ;
     //进行那个CPU的循环调用
     while(pcbc->ready != NULL)
     {
         pcbc->run = pcbc->ready ; //将就绪队列队首加入运行队列
         pcbc->ready = pcbc->ready->next ; //改变队首元素
         print_log(pcbc) ;
         pcbc->run->take_cpu_time += 1 ;
         pcbc->run->process_time -= 1 ;
         if(pcbc->run->process_time == 0)
         {
           if(pcbc->finish == NULL)
           {
               pcbc->finish = pcbc->run ;
               pcbc->finish->next = NULL ;
               tail = pcbc->finish ;
           }
           else
           {
              tail->next = pcbc->run ;
              tail = tail->next ;
              tail->next = NULL ;
           }
         }
         else
         {
            if(pcbc->run->time_slice == pcbc->run->take_cpu_time) //占用CPU时间片数到
            {
                //将其加入队尾
                pcbc->run->take_cpu_time = 0 ;
                pcbc->run->next = NULL ;
                pcbc->tail->next = pcbc->run ;
                pcbc->tail = pcbc->run ;
                if(pcbc->ready == NULL)
                {
                    pcbc->ready = pcbc->tail ;
                    pcbc->ready->next = NULL ;
                }
            }
            else
            {
                pcbc->run->next = pcbc->ready ;
                pcbc->ready = pcbc->run ;
            }
         }
     }
     pcbc->run = NULL ;
     print_log(pcbc) ;
}
int main()
{
    PCBC *pcbc ; //创建进程控制块链 ;
    int pcb_num ; //记录处理进程数目
    pcbc = (PCBC*)malloc(sizeof(PCBC)) ;
    printf("请输入要处理的进程数目: ") ;
    scanf("%d" , &pcb_num) ;
    init_pcbc(pcbc) ; //初始化进程控制块链
    for(int i = 0 ; i < pcb_num ; i++)
    {
        input_process(pcbc) ; //输入所有进程,并进入就绪队列
    }
    //通过时间片轮转调度算法
    printf("By the time slice------------------------\n") ;
    run_pcbc_timeSlice(pcbc) ;
    return 0 ;
}
  • 39
    点赞
  • 323
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
基于优先时间轮转调度算法是一种常用的调度算法,它能够实现公平地分配处理器时间,并根据进程的优先级调整时间片的分配。以下是基于优先时间轮转调度算法调度处理器的过程: 1. 首先,所有进程按照优先级进行排序。优先是根据进程的特征和属性来确定的,比如进程的重要性、紧迫程度、运行时间等。 2. 然后,为每个进程分配一个初始时间片,时间片是处理器在一次调度中分配给每个进程的时间单位,它决定了每个进程执行的时间长度。 3. 处理器选择优先级最高的进程,并从该进程开始执行。 4. 执行进程的时间称为时间片。当时间片耗尽时,处理器将停止执行当前进程,并将其放入就绪队列的末尾。 5. 处理器选择就绪队列中的下一个进程,并分配给它一个新的时间片。这个过程将不断轮转,直到所有进程完成执行。 基于优先时间轮转调度算法的优点是能够根据进程的优先级来调整时间片的分配,提高了重要进程和紧急进程的响应速度。同时,该算法也实现了公平性,避免了某些进程长时间占用处理器的情况。 然而,基于优先时间轮转调度算法也存在一些问题。首先,如果存在相同优先级的进程,这些进程可能会由于时间片用完而被强制停止,导致进程切换频繁,降低系统性能。其次,该算法对长作业有不利影响,因为长作业可能需要多次的时间轮转才能完成。因此,该算法通常用于实时系统和需要响应时间较短的环境中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值