操作系统之处理机调度

Posted 夏芷雨涵梦

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了操作系统之处理机调度相关的知识,希望对你有一定的参考价值。

题目描述:

在处理机三级调度系统中,编程仿真作业调度与进程调度。作业调度采用短作业优先的方式,进程调度采用优先级方式或时间片轮转方式。

源代码:

#include <iostream>
#include <stdlib.h>
#include <cstdio>
#define TIMELIMIT 6
#define PriLimit 5
#define work 5
using namespace std;

struct JCB     //作业

    int jname;    //作业名
    int start;    //到达时间
    int priority;    //优先级
    int worktime;    //工作时间
    JCB *next;    //链接指针
;

struct PCB


    int pname;    //进程名
    int time;    //进程运行时间
    char state;    //运行状态
    PCB* next;
;

void CreateJob(JCB* jobtable,int name)    //创建作业,将作业放入作业调度表

    //随机生成一个作业
    JCB *p = new JCB;
    p->jname=name;
    p->start = rand()%5+1;
    p->worktime = rand()%TIMELIMIT+1;
    p->priority = rand()%PriLimit+1;
    p->next = NULL;

    JCB* now = jobtable;
    if(now->next==NULL)
    
        now->next = p;
    
    else
    
        if(p->start <= now->next->start)//新插入的作业到达时间比表中的第一个小,将新到的插入到表头
        
            p->next = now->next;
            now->next = p;
        
        else//新插入的作业到达时间比表中的第一个大,向后查找
        
            JCB *q = now->next;
            while( (p->start > q->start) && (q->next!=NULL) )
            
                q = q->next;
            
            if( (p->start > q->start) && q->next==NULL) //比所有的都大,放到最后
            
                q->next = p;
            
            else if(p->start <= q->start)
            
                JCB *t = now->next;
                while(t->next!=q)  //找到前驱节点
                
                    t = t->next;
                
                t->next = p;
                p->next = q;
            
        
    


void AddHoubei(JCB *jobtable,JCB *p,JCB *&jhead)    //将作业p放入后备队列jhead,按短作业优先放置

    JCB* q = jobtable;
    while(q->next!=p && q->next!=NULL)// 找到p的前驱节点
    
        q = q->next;
    
    if(q->next==p)
    
        q->next = p->next;
        p->next = NULL;
    

    if(jhead==NULL)
    
        jhead = p;
    
    else
    
        if(p->worktime <= jhead->worktime)//优先级小的放在前边
        
            p->next = jhead;
            jhead = p;
        
        else
        
            JCB *q = jhead;
            while( (p->worktime > q->worktime) && (q->next!=NULL) )
            
                q = q->next;
            
            if( (p->worktime > q->worktime) && q->next==NULL) //比所有的都大,放到最后
            
                q->next = p;
            
            else if(p->worktime <= q->worktime)
            
                JCB *t = jhead;
                while(t->next!=q)  //找到前驱节点
                
                    t = t->next;
                
                t->next = p;
                p->next = q;
            
        
    


void CreateProcess(PCB* &head,PCB* &tail,JCB* &jhead)    //创建新进程

    PCB* p = new PCB;
    p->pname = jhead->jname;
    p->state = 'R';    //就绪状态
    p->time = jhead->worktime;        //进程工作时间

    if(tail==NULL)
    
        //就绪队列还是空的,则第一次赋值
        head = p;
        tail = head;
        tail->next = head;
    
    else
    
        //就绪队列不为空
        tail->next = p;
        tail = p;
        p->next = head;
    



void DropPro(PCB* &head,PCB* &tail,PCB* &chead,PCB* &ctail)    //将队首进程,推出循环就绪队列

    PCB* p = head;        //保存头节点
    head = head->next;    //头结点指向他的下一个节点
    tail->next = head;    //将就绪队列尾节点直接指向新的头节点
    p->next = NULL;        //将分离出来的原来的头节点的next设为空NULL

    if(ctail==NULL)
    
        //已完成进程队列还是空的,则第一次赋值
        chead = p;
        ctail = chead;
    
    else
    
        //已完成进程队列不为空,则将当前已完成进程放到队列尾部
        ctail->next = p;
        ctail = ctail->next;
    


void Work(PCB* now)    //当前进程执行

    now->time--;


void NextPro(PCB* &head,PCB* &tail)    //当前进程已执行了一个时间片,将其置于循环队列尾端。即将head和tail向前推进一次

    head = head->next;
    tail = tail->next;

void printRQ(PCB* head,int readynum)    //打印当前就绪队列

    PCB* p = head;
    printf("\\t--- 就绪队列 ---\\n");
    printf("进程名\\t");
    printf("所需时间\\t");
    printf("进程状态\\n");
    if(readynum==0)
    
        //就绪队列已空
        printf("空\\n");
        return ;
    
    while(p->next!=head)
    
        printf("%d\\t",p->pname);
        printf("%d\\t\\t",p->time);
        printf("%c\\n",p->state);
        p = p->next;
    
    printf("%d\\t",p->pname);
    printf("%d\\t\\t",p->time);
    printf("%c\\n",p->state);


void printCQ(PCB* chead,PCB* ctail)    //打印当前已完成进程队列

    PCB* p = chead;
    printf("\\t--- 已完成进程 ---\\n");
    printf("进程名\\t");;
    printf("进程状态\\n");
    if(chead==NULL)
    
        //已完成进程队列队列已空
        printf("空\\n");
        return ;
    
    while(p!=ctail)
    
        printf("%d\\t",p->pname);
        printf("%c\\n",p->state);
        p = p->next;
    
    printf("%d\\t",p->pname);
    printf("%c\\n",p->state);

void printJQ(JCB* jhead)    //打印当前后备队列

    JCB * p = jhead;
    printf("\\t--- 后备队列 ---\\n");
    printf("作业名\\t");
    printf("到达时间\\t");
    printf("工作时间\\n");
    if(jhead==NULL)
    
        printf("空\\n");
        return ;
    
    while(p->next!=NULL)
    
        printf("%d\\t",p->jname);
        printf("%d\\t\\t",p->start);
        printf("%d\\n",p->worktime);
        p = p->next;
    
    printf("%d\\t",p->jname);
    printf("%d\\t\\t",p->start);
    printf("%d\\n",p->worktime);

void printProInfo(PCB* now)    //打印当前进程信息

    if(now==NULL)
    
        printf("当前没有进程\\n");
        return ;
    
    printf("\\t--- 运行队列 ---\\n");
    printf("进程名:\\t");
    printf("运行时间:\\t");
    printf("进程状态:\\n");
    printf("%d\\t",now->pname);
    printf("%d\\t\\t",now->time);
    printf("%c\\n",now->state);

void printAllJobInfo(JCB* jhead)    //输出作业调度表

    JCB* p = jhead->next;
    printf("\\t--- 作业调度表 ---\\n");
    printf("作业名\\t");
    printf("到达时间\\t");
    printf("工作时间\\n");
    while(p!=NULL)
    
        printf("%d\\t",p->jname);
        printf("%d\\t\\t",p->start);
        printf("%d\\n",p->worktime);
        p = p->next;
    


int main()

    PCB *head=NULL,*tail=NULL;    //就绪队列
    JCB *jhead=NULL;    //后备队列
    PCB *chead=NULL,*ctail=NULL;    //已完成进程队列
    JCB *jobtable = new JCB;    //作业调度表
    int tablenum=5;    //作业调度表中作业数量
    int houbeinum=0;    //后备队列的作业数量
    int readynum=0;     //就绪队列的作业数量
    jobtable->next = NULL;
    for(int i=1; i<6; i++)
        CreateJob(jobtable,i);
    printAllJobInfo(jobtable);    //输出作业调度表
    printf("\\t---开始时间片轮转---\\n");
    printf("********************************\\n");
    int curtime=0;
    while(readynum!=0 || houbeinum!=0 || tablenum!=0)     //直到就绪队列为空 且 后备队列为空 且 作业调度表为空,退出循环
    
        printf("当前系统时间为%d\\n",curtime);
        JCB* p = jobtable->next;
        while(p!=NULL)
        
            if(p->start==curtime)     //有作业到达,将作业放入后备队列,并按短作业优先放置
            
                JCB *t = p->next;
                printf("将作业%d投入到后备队列\\n",p->jname);
                AddHoubei(jobtable,p,jhead);
                printAllJobInfo(jobtable);     //输出调度表
                printJQ(jhead);                 //输出后备队列
                houbeinum++;    //后备队列
                tablenum--;    //作业调度表
                p = t;
            
            else
            
                p = p->next;
            
        
        //
        //
        if(readynum==3)     //已满
        
            printJQ(jhead);       //输出后备队列
            printRQ(head,readynum);      //输出就绪队列
        
        else     //未满,从后备队列中将作业放入就绪队列
        
            if(houbeinum!=0&&readynum<3)     //后备队列不为空并且就绪队列不满
            
                CreateProcess(head,tail,jhead);    //将作业投入到就绪队列
                printf("将作业%d投入到就绪队列\\n",jhead->jname);

                jhead = jhead->next;    //指向后备队列下一个作业
                readynum++;    //就绪队列
                houbeinum--;    //后备队列
                printJQ(jhead);       //输出后备队列
                printRQ(head,readynum);      //输出就绪队列
            
        

        //已空就算了
        PCB* now = head;
        if(now!=NULL)     //当前就绪队列不为空时运行进程
        
            //将该进程放入运行队列
            //rhead = now;
            printf("将%d进程放入运行队列\\n",now->pname);
            printProInfo(now);
            Work(now);    //执行当前进程

            if(now->time==0)
            
                now->state = 'C';    //设置进程为已完成状态
                printf("# 进程%d已完成,退出就绪队列\\n",now->pname);
                DropPro(head,tail,chead,ctail);    //推出循环就绪队列
                printCQ(chead,ctail);
                readynum--;
                if(readynum==0)
                
                    head = 0;
                    tail = 0;
                
            
            else
            
                NextPro(head,tail);    //已完成,将其置于循环队列尾端。即将head和tail向前推进一次
            

        
        curtime++;
        printf("--------------------------------\\n");
    
    printf("********************************\\n");
    return 0;

 

以上是关于操作系统之处理机调度的主要内容,如果未能解决你的问题,请参考以下文章

操作系统学习笔记

操作系统之处理机调度

❤️过万字详细《操作系统-进程管理》❤️⭐建议收藏⭐

❤️过万字详细《操作系统-进程管理》❤️⭐建议收藏⭐

Linux环境之进程调度算法

操作系统之进程调度