动态高优先权优先调度

实验二  动态高优先权优先调度

实验内容:

模拟实现动态高优先权优先(若数值越大优先权越高,每运行一个时间单位优先权-n,若数值越小优先权越高,没运行一个时间单位优先权+n),具体如下:

设置进程体:进程名,进程的到达时间,服务时间,初始优先权,进程状态(W——等待,R——运行,F——完成),进程间的链接指针

进程初始化:由用户输入进程名、服务时间、初始优先权进行初始化,同时,初始化进程的状态为W。

显示函数:在进程调度前、调度中和调度后进行显示。

排序函数:对就绪状态的进程按照优先权排序。优先权相同时进入等待队列时间早的进程在前。注意考虑到达时间

调度函数:每次从等待队列队首调度优先权最高的进程执行,状态变化。并在执行一个时间单位后优先权变化,服务时间变化,状态变化。当服务时间为0时,状态变为F。

删除函数:撤销状态为F的进程。

实验要求:

  1. 测试数据可以随即输入或从文件中读入。
  2. 必须要考虑到进程的到达时间
  3. 最终能够计算每一个进程的周转时间。

因为做的测试样例不多,希望有错误的地方能给予指出~~感谢.jpg

/*
动态高优先权优先调度
*/
#include<bits/stdc++.h>
using namespace std;
struct Job
{
    int pid;
    int startTime;//到达时间
    int readTime;//进入准备队列的时间
    int runTime;//运行时间
    int serverTime;//服务时间
    int status;//0==等待,1==运行,2==完成
    int weight;//优先权,值越大,优先权越高
    int finishTime;//完成时间
} job[100001];
int n;//所有作业数量
int x;//没过一个时间单位权重的变化
bool operator <(const Job& a,const Job& b)//结构体重载函数
{
    if(a.weight == b.weight)
        return a.readTime>b.readTime;//优先权相等,更早进入准备队列的优先
    return a.weight<b.weight;
}
bool cmp(Job a,Job b)
{
    return a.startTime<b.startTime;
}
priority_queue<Job> ReadQueue;//进程准备队列


void updateStatus(int id,int time,int sta,int run,int we,int read)//修改进程状态
{
    for(int i=0; i<n; i++)
    {
        if(job[i].pid == id)
        {
            job[i].weight = we;
            job[i].runTime = run;
            job[i].finishTime = time;
            job[i].status = sta;
            job[i].readTime = read;
            break;
        }
    }
}
int main()
{
    printf("请输入进程数量:");
    scanf("%d",&n);
    printf("请输入进程ID,进程到达时间,进程服务时间,进程初始权重:\n");
    for(int i=0; i<n; i++)
    {
        scanf("%d %d %d %d",&job[i].pid,&job[i].startTime,&job[i].serverTime,&job[i].weight);
        job[i].status = 0;
        job[i].runTime = 0;
        job[i].readTime = job[i].startTime;
    }
    printf("请输入每过一个时间单位权值的变化:");
    scanf("%d",&x);
    sort(job,job+n,cmp);//按到达时间排序
    Job text;//临时队首的进程作业
    int nowJob = 0;//已经进入准备队列的进程数量
    for(int i=0; ; i++)//时间刻度,当nowJob==n && 准备队列为空时跳出循环
    {
        printf("第%d时刻:\n",i);
        for(int j=nowJob; j<n; j++)//如果开始时刻等于当前时刻,将作业压入准备队列
            if(job[j].startTime == i && job[i].status == 0)
                ReadQueue.push(job[j]),nowJob++,text.readTime = i;
            else break;
        if(!ReadQueue.empty())//如果当前时刻准备队列不为空
        {
            text = ReadQueue.top();//取出当前准备队列队首并移除
            ReadQueue.pop();
            //当前队首进行工作,工作一个时间单位之后,权值变化并重新进入准备队列
            text.runTime++;//运行时间+1;
            text.status = 1;//状态设为正在运行
            printf("正在运行的进程ID:%d号进程\n",text.pid);
            if(text.runTime == text.serverTime)//如果运行时间==服务时间,就结束
            {
                text.finishTime = i+1;//完成时间
                //这里完成时间为i+1,以0时刻开始,运行一个单位,那么在这里就结束了
                //但是理论的结束时间应该为后一个时间单位,所以为i+1
                text.status = 2;//状态设为2
                text.readTime = i+1;
                updateStatus(text.pid,text.finishTime,text.status,text.runTime,text.weight,text.readTime);
                continue;//下一时刻

            }
            else//如果没有结束
            {
                text.weight-=x;//权重减少
                text.readTime = i+1;//重新进入队列的时间
                ReadQueue.push(text);//重新进入准备队列
                updateStatus(text.pid,text.finishTime,text.status,text.runTime,text.weight,text.readTime);//修改进程状态
            }
        }
        for(int j=0; j<n; j++)
        {

            printf("id:%d\t上次进入队列时刻:%d\t状态:%d\t运行时间:%d\t当前权重%d\t结束时间:%d\n",job[j].pid,job[j].readTime,job[j].status,job[j].runTime,job[j].weight,job[j].finishTime);
        }
        if(ReadQueue.empty() && nowJob == n)//如果队列为空并且所有进程作业都已入队,说明完成
            break;//跳出循环
    }

    for(int i=0; i<n; i++)
        printf("%d %d %d\n",job[i].pid,job[i].startTime,job[i].finishTime);

    return 0;
}

 

  • 10
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 18
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值