处理机调度算法分析及C语言实现

 本博客最后更新于2018年12月29日,不知道CSDN到底出什么毛病了,之前上传的代码莫名其妙丢掉了几行语句。为防止再次丢失代码,我这次把cpp文件和word文档都上传到了百度网盘里,这是链接:https://pan.baidu.com/s/1LixFnRYsR6X7YAFAzairPw

    1. 处理机调度的目的是什么?

答:在多道程序环境下,主存中有着多个进程,其数目往往多于处理机数目。这就要求系统能按某种算法,动态地把处理机分配给就绪队列中的一个进程,使之执行。处理机调度就是为了分配处理机,提高处理机的利用率及改善系统性能。

    1. 处理机调度的算法有哪些,各自的优缺点是什么?

答:处理机调度算法有:先来先服务(FCFS)调度算法,短作业(进程)优先调度算法SJ(P)F,高优先权优先(FPF)调度算法和基于时间片的轮转调度算法。

各算法的优点:

FCFS调度算法比较有利于长作业(进程);

相较于FCFS算法,SJ(P)F调度算法能有效地降低作业的平均等待时间,提高系统吞吐量;

相较于SJ(P)F算法,FPF调度算法照顾了紧迫型作业,使之在进入系统后便获得优先处理;

基于时间片的轮转调度算法可以保证就绪队列中的所有进程在一给定的时间内均能获得一时间片的处理机执行时间。

各算法的缺点:

FCFS调度算法不利于短作业(进程);

SJ(P)F调度算法对长作业(进程)不利,可能导致长作业(进程)长期不被调用;且未考虑作业的紧迫程度,不能保证紧迫性作业(进程)得到及时处理;由于作业(进程)的长短只是根据用户所提供的估计时间而定的,而用户对作业(进程)的估计运行时间可能不准确,致使该算法不一定能真正做到短作业优先;

相较于SJ(P)F算法和FCFS算法,FPF调度算法花费的系统开销比较大;

 

    1. 基于时间片的轮转调度算法同样未考虑作业的紧迫程度,不能保证紧迫性作业(进程)得到及时处理。基于两种处理机调度算法,分别解答例题中的三个问题;
  • 列出不同时刻下内存中的运行作业序列;

 

1

3

4

6

8

13

15

A

B

B

A

C

D

 

 

A

A

D

D

 

 

 

  • 列出所有作业进入内存的时刻及结束时刻;

 

进程名

到达时刻

进入内存的时刻

结束时刻

周转时间

A

1

1

8

7

B

3

3

6

3

C

4

8

13

9

D

6

6

15

9

 

  • 计算平均周转时间。

 

平均周转时间 = ∑(周转时间)/进程数 = (7+3+9+9) / 4 = 7

 

算法程序

有一个具有两道作业的批处理系统,作业调度采用短作业优先的调度算法,进程调度采用以优先数为基础的抢占式调度算法(进程优先数越小,优先级越高)。

(1)流程图

(2)以下代码是用C语言的,其中有几句输出语句用的是C++的“cout”函数。本代码在VS上亲测可用大笑

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace std;

typedef struct node
{
	char id;
	int cputime;
	int needtime;
	int priority;
}PCB;		//定义PCB结构体

#define jobNum 7		//作业数量
#define batch  2		//批处理作业个数

PCB pcb[jobNum];			//pcb数组用来保存所有作业的信息,其大小等于作业数量
PCB memory[2];		//memory数组用来保存被调入到主存中的所有作业信息,其大小等于批处理作业个数
PCB wait[jobNum-batch];		//wait数组用来保存已到达作业,但没能被调入到主存中的作业。其大小等于jobNum-batch
int memoryNum = 0;	//调入至主存中的作业个数。初始化为0
int waitNum = 0;	//等待被调入的作业个数。初始化为0
int MaxTime = 1000;	//定义最大的完成时间100
float totalTime = 0;	//保存总的周转时间
float totalEndTime = 0;  //保存总的结束时间

void sort(PCB *pcb, int count, char key);
void process(int currentTmp, int nextTmp);

int main(void)
{
    PCB *tmp = (PCB*)malloc(sizeof(PCB));
    char id;
    int cputime, needtime, priority;
    int i, j;
    int current, next;

    printf("输入进程名(char),到达时间(int),所需运行时间(int),优先数(int). 【按到达时间由先到后进行输入】\n");
    for (i = 0; i<jobNum; i++)
    {
        //getchar();
        //setbuf(stdin, NULL);       //清空输入缓冲
        rewind(stdin);
        printf("请输入第 %d 个作业的相关信息\n", i + 1);
        scanf("%c%d%d%d", &id, &cputime, &needtime, &priority);
        tmp->id = id;
        tmp->cputime = cputime;
        tmp->needtime = needtime;
        tmp->priority = priority;
        pcb[i] = *tmp;
    }

    for (i = 0; i<jobNum; i++)
    {
        printf("作业 %c 的到达时间,所需运行时间,优先数分别为: %d, %d, %d;\n", pcb[i].id, pcb[i].cputime, pcb[i].needtime, pcb[i].priority);
    }

    //逐个处理作业
    cout << "\n不同时刻下内存中的运行作业序列、各作业进入内存的时刻及结束时刻: \n\n";
    for (i = 0; i < jobNum; i++)
    {
        current = pcb[i].cputime;
        if (i == jobNum - 1)        //说明是最后一个作业
            next = MaxTime;
        else
            next = pcb[i + 1].cputime;    //保存下一个进程到达的时间。注意不能越界

                                        //先将作业放到wait中,再排序
        wait[waitNum] = pcb[i];
        waitNum++;
        if (next == current) continue;         //两个作业同时到达后备队列
        if (waitNum > 1)
            sort(wait, waitNum, 'N');

        while (memoryNum < 2 && waitNum>0)        //若当前主存中作业数量小于2,则把当前进程放入到主存中
        {
            memory[memoryNum] = wait[0];
            cout << "作业 " << memory[memoryNum].id << " 进入内存的时刻是:" << current << '\n';
            memory[memoryNum].cputime = current;
            memoryNum++;
            waitNum--;
            for (j = 1; j <= waitNum; j++)
                wait[j - 1] = wait[j];
            sort(memory, memoryNum, 'P');
        }
        process(current, next);        //调用process时,memoryNum至少为1

    }//end for

    for (i = 0; i < jobNum; i++)
    {
        totalTime -= pcb[i].cputime;
    }

    //平均周转时间
    if (totalEndTime > 0) cout << "\n平均周转时间是:" << (totalEndTime + totalTime) / jobNum << "\n\n";
    return 0;
}
void process(int currentTmp, int nextTmp)
{
    int leftTime = memory[0].needtime - nextTmp + currentTmp;  //memory[i].needtime-(nextTmp-currentTmp)
    if (leftTime <= 0)       //下一个作业到达时,本作业已运行结束
    {
        cout << "  " << currentTmp << "    "; //输出不同时刻下内存中的运行作业序列、所有作业进入内存的时刻及结束时刻
        currentTmp += memory[0].needtime;  //修改当前时间
        memoryNum--;
        memory[0].needtime = 0;
        cout << memory[0].id << "    ";
        if (memoryNum > 0)
        {
            cout << memory[1].id << '\n';
            cout << "作业 " << memory[0].id << " 的结束时刻是:" << currentTmp << '\n';
            memory[0] = memory[1];
        }
        else cout << "空\n";
        totalEndTime += currentTmp;
    }
    else          //下一个作业到达时,本作业未运行结束
    {
        cout << "  " << currentTmp << "    ";
        cout << memory[0].id << "    ";
        if (memoryNum == 2) cout << memory[1].id << '\n';
        else cout << "空\n";
        currentTmp = nextTmp;
        memory[0].needtime = leftTime;
        if (currentTmp == MaxTime)       //当前时间已到最大完成时间
        {
            cout << "  " << currentTmp << "    " << memory[0].id << "    超时\n\n";
            totalEndTime = -1;
            return;
        }
    }
    if (nextTmp == MaxTime)
    {
        if (waitNum > 0)
        {
            memory[1] = wait[0];
            waitNum--;
            if (waitNum > 0)
            {
                for (int j = 1; j <= waitNum; j++)
                    wait[j - 1] = wait[j];
            }
            memoryNum++;
            cout << "作业 " << memory[1].id << " 进入内存的时刻是:" << currentTmp << '\n';
            sort(memory, memoryNum, 'P');
        }
        if (memoryNum == 0)
        {
            cout << "  " << currentTmp << "    空    空\n";
            cout << "作业 " << memory[0].id << " 的结束时刻是:" << currentTmp << '\n';
            return;
        }
        process(currentTmp, nextTmp);
    }
}

//选择排序算法,若key为'P'则按优先级大的排在数组首,否则为'N'则按所需时间进行短作业优先排序
void sort(PCB *pcb, int count, char key)
{
    PCB basic;
    if (key == 'N')
    {
        for (int a = 0; a<count; a++)
            for (int b = 1; b<count - a; b++)
            {
                if (pcb[a].needtime>pcb[a + 1].needtime)
                {
                    basic = pcb[a];
                    pcb[a] = pcb[a + 1];
                    pcb[a + 1] = basic;
                }
            }
    }
    else
    {
        if (count == 2)
        {
            for (int a = 0; a < count; a++)
                for (int b = 1; b < count - a; b++)
                {
                    if (pcb[a].priority > pcb[a + 1].priority)
                    {
                        basic = pcb[a];
                        pcb[a] = pcb[a + 1];
                        pcb[a + 1] = basic;
                    }
                }
        }
    }
}/* 测试用例
A 1 4 5
B 3 3 3
C 4 5 4
D 6 2 6
E 6 100 2
F 100 500 1
G 200 100 6
*/


  • 4
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值