操作系统实验——处理器调度

处理器调度实验——FCFS, RR, SPN, SRT, HRRN

实验题目

随机给出一个进程调度实例,如:
进程 到达时间 服务时间
A 0 3
B 2 6
C 4 4
D 6 5
E 8 2
模拟进程调度,给出按照算法先来先服务FCFS、轮转RR(q=1)、最短进程优先SPN、最短剩余时间SRT、最高响应比优先HRRN进行调度各进程的完成时间、周转时间、响应比的值。

代码

#include <iostream>
#include <queue>
using namespace std;

#define MAX_TASK 128 //最多线程数
struct A
{
    char name;      //进程名称
    int arrive;     //到达时间
    int time;       //服务时间
    int start;      //开始时间
    int end;        //结束时间
    float rate;     //响应比
    bool activated; //是否到达
    int rest;       //剩余时间
};

/*
结束时间=开始时间+服务/执行时间(无抢断)
周转周期=结束时间-到达时间
响应比的值(带权周转时间)=周转时间/服务时间
       =(结束时间-到达时间)/服务时间
*/

void FCFS(A a[], int n)
{
    //先来先服务是最简单的策略,也成为先进先出FIFO。首先它是一个非抢占的。
    //如字面的意思,它根据进程到达时间决定先运行哪一个进程。

    for (int i = 0; i < n; i++)
    {
        if (i > 0 && a[i].arrive < a[i - 1].end)
        {
            a[i].start = a[i - 1].end;
            a[i].end = a[i].start + a[i].time;
        }
        else
        {
            a[i].start = a[i].arrive;
            a[i].end = a[i].start + a[i].time;
        }

        a[i].rate = (float)(a[i].end - a[i].arrive) / a[i].time; //求相应比
        cout << a[i].name << " " << a[i].end << " " << a[i].end - a[i].arrive << " " << a[i].rate << endl;
        //进程名 进程结束时间 周转周期 响应比
    }
}

void RR(A a[], int n)
{
    //轮转也称时间片技术(time slicing,SL),对于轮转法,最重要的是时间片的长度
    //转算法以一个周期(q)产生中断,当中断发生时,当前运行的程序置于就绪队列(队尾)
    //中,然后基于FCFS选择下一个就绪作业运行
    queue<A> q;//轮转队列
    A temp;
    A b[MAX_TASK];

    for (int i = 0; i < n; i++)
    {
        b[i] = a[i];
    }

    int time_now = 0;
    q.push(a[0]);
    while (!q.empty())
    {
        time_now++;
        temp = q.front();
        q.pop();//删除队首元素
        temp.time--;

        for (int i = 1; i < n; i++)
        {
            if (a[i].arrive == time_now)//就绪进程进入队尾
            {
                q.push(a[i]);
            }
        }
        if (temp.time != 0)//当前进程未运行完
        {
            q.push(temp);//把当前运行进程插入队尾
        }
        else
        {
            temp.end = time_now;
            for (int i = 0; i < n; i++)
            {
                if (temp.name == a[i].name)
                {
                    a[i] = temp;
                    a[i].rate = (float)(a[i].end - a[i].arrive) / b[i].time;
                }
            }
        }
    }
    for (int i = 0; i < n; i++)
    {
        cout << a[i].name << " " << a[i].end << " " << a[i].end - a[i].arrive << " " << a[i].rate << endl;
    }
}

void SPN(A a[], int n) //最短进程优先SPN
{
    //最短作业优先(Short Job First,SJF)。
    //它也是一个非抢占的。是根据服务的时间经行选择。
    //要注意下到达时间的顺序,有多个进程等待时选择服务时间最少的进程

    int now = 0;                //正在运行进程标志
    int min = 100;              //最短进程时间
    int time_now = a[0].arrive; //标志当前时间
    //假设输入默认按到达时间升序或默认a[0]最早到达

    for (int i = 0; i < n; i++)
    {
        for (int k = 0; k < n; k++) //检查所有进程,是否已到达
        {
            if (a[k].arrive <= time_now && a[k].time != 0) //获取到达的进程
            {
                a[k].activated = true;
            }
        }

        for (int l = 0; l < n; l++) //循环遍历找到当前既到达又最短的进程 a[now]
        {
            if (a[l].time < min && a[l].activated == true)
            {
                min = a[l].time;
                now = l;
            }
        }

        a[now].start = time_now;
        a[now].end = a[now].start + a[now].time; //当前进程结束时间
        time_now = a[now].end;                   //下一个进程开始时间
        a[now].rate = (float)(a[now].end - a[now].arrive) / a[now].time;
        a[now].activated = false;
        a[now].time = 0; //去除当前进程
        min = 100;
    }

    for (int i = 0; i < n; i++) //输出
    {
        cout << a[i].name << " " << a[i].end << " " << a[i].end - a[i].arrive << " " << a[i].rate << endl;
    }
}

void SRT(A a[], int n) //最短剩余时间优先SRT
{
    //SRT是针对SPN增加了抢占机制的版本,
    //就好比某个进程运行时间非常长,在这期间其他所有的进程都在等待,
    //如果将其中断,先处理所需时间少的,运行效率会有显著提升。
    int now = 0;                //正在运行进程标志
    int min = 100;              //最短进程时间
    int time_now = a[0].arrive; //标志当前时间
    //假设输入默认按到达时间升序

    for (int i = 0; i < n; i++)
        a[i].rest = a[i].time;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0;; j++)
        {
            for (int k = 0; k < n; k++) //检查所有进程,是否已到达
            {
                if (a[k].arrive <= time_now && a[k].time != 0) //获取到达的进程
                {
                    a[k].activated = true;
                }
            }

            for (int l = 0; l < n; l++) 
            {
                if (a[l].rest < min && a[l].activated == true)//找到当前既到达剩余又最短的进程 a[now]
                {
                    min = a[l].rest;
                    now = l;
                }
            }
            a[now].start = time_now;
            int m = 0;
            for (m = 0; m < n; m++)
            {
                if (m != now && a[m].arrive < time_now + a[now].rest && a[m].time != 0 && a[m].activated == false)
                {//找到当前到达的进程
                    time_now = a[m].arrive;
                    a[now].rest = a[now].start + a[now].rest - time_now;
                    if (a[m].rest < a[now].rest)//抢断
                    {
                        now = m;
                        break;
                    }
                }
            }
            if (m == n)//当前进程未被抢断,运行完成
            {
                a[now].end = time_now + a[now].rest;
                time_now = a[now].end; //下一个进程开始时间
                a[now].rate = (float)(a[now].end - a[now].arrive) / a[now].time;
                a[now].activated = false;
                a[now].time = 0; //去除当前进程
                break;
            }
        }
        min = 100;
    }

    for (int i = 0; i < n; i++) //输出
    {
        cout << a[i].name << " " << a[i].end << " " << a[i].end - a[i].arrive << " " << a[i].rate << endl;
    }
}

void HRRN(A a[], int n) //高响应比优先HRRN
{
    //高响应比优先调度算法主要用于作业调度,
    //该算法是对FCFS调度算法和SJF调度算法的一种综合平衡,
    //同时考虑每个作业的等待时间和估计的运行时间。在每次进行作业调度时,
    //先计算后备作业队列中每个作业的响应比,从中选出响应比最高的作业投入运行
    //A 3 3 1
    //B 9 7 1.16667
    //C 13 9 2.25
    //D 20 14 2.8
    //E 15 7 3.5

    int now = 0;                //正在运行进程标志
    int min = 1;                //最短进程时间
    int time_now = a[0].arrive; //标志当前时间
    //假设输入默认按到达时间升序或默认a[0]最早到达

    for (int i = 0; i < n; i++)
    {
        for (int k = 0; k < n; k++) //检查所有进程,是否已到达
        {
            if (a[k].arrive <= time_now && a[k].time != 0) //获取到达的进程
            {
                a[k].activated = true;
            }
        }

        for (int l = 0; l < n; l++) //循环遍历找到当前既到达又响应比最高 a[now]
        {
        
            if (a[l].activated == true && a[l].time != 0)
            {
                a[l].rate = (float)(time_now + a[l].time - a[l].arrive) / a[l].time;
                //计算当前响应比
            
                if (min < a[l].rate)//找出相应比高的进程
                {
                    min = a[l].rate;
                    now = l;
                }
            }
        }
       

        a[now].start = time_now;
        a[now].end = a[now].start + a[now].time; //当前进程结束时间
        time_now = a[now].end;                   //下一个进程开始时间
        a[now].time = 0; //去除当前进程
        min = 1;
    }

    for (int i = 0; i < n; i++) //输出
    {
        cout << a[i].name << " " << a[i].end << " " << a[i].end - a[i].arrive << " " << a[i].rate << endl;
    }
}
int main()
{
    A a[MAX_TASK];
    int num;
    cin >> num;	

    //输入
    for (int i = 0; i < num; i++)
    {
        cin >> a[i].name;
        cin >> a[i].arrive;
        cin >> a[i].time;
        a[i].activated = false;
        a[i].rate = 1;
    }
    string method;
    cin >> method; //获取算法名称

	/*请在以下区域填入代码*/
	if (method == "FCFS")
	{
		FCFS(a, num);
	}
	if (method == "RR")
	{
		RR(a, num);
	}
	if (method == "SPN")
	{
		SPN(a, num);
	}
	if (method == "SRT")
	{
		SRT(a, num);
	}
	if (method == "HRRN")
	{
		HRRN(a, num);
	}

    system("pause");
    return 0;
}
  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值