几种优先级调度算法合并

本文介绍了三种操作系统调度算法:先来先服务(FCFS)、最短作业优先(SJF)和抢占式优先级调度。每种算法都有详细的实现过程和示例,包括进程的到达时间、服务时间、优先级等关键参数,并展示了如何计算周转时间和带权周转时间。代码示例展示了如何使用C++实现这些算法,帮助理解调度过程。
摘要由CSDN通过智能技术生成

先来先服务算法

短进程优先级算法

非抢占式优先级调度算法

抢占式优先级调度算法

#include <iostream>
#include <queue> //优先级队列
#include <algorithm>
#include <cstdio>
#include <cstring>

using namespace std;
const int MAXN = 1000;
int n;

//先来先服务和短进程优先结构体
struct ProcessFS
{
    int pos;                          //代表第几个输入的进程
    char Process_name[50];            //进程名字,默认最长长度占用50字符
    double Arrival_time;             //进程到达时间
    double Service_time;             //服务时间       进程所需要的时间
    double Start_time;               //服务开始时间
    double End_time;                 //服务结束的时间
    double turnroundTime;   //周转时间
    double  weightedTurnaroundTime;//带权周转时间
    double Priority;                 //优先权,这里面的优先级权是不能修改的!!!
    bool operator < (const ProcessFS & a)const
    {


        if (Service_time == a.Service_time)
            return Arrival_time > a.Arrival_time;
        return Service_time > a.Service_time;

    }
}processFS[MAXN];   //结构体数组
//非抢占式优先级结构体
struct ProcessNP
{
    int pos;                          //代表第几个输入的进程
    char Process_name[50];            //进程名字,默认最长长度占用50字符
    double Arrival_time;             //进程到达时间
    double Service_time;             //服务时间       进程所需要的时间
    double Start_time;               //服务开始时间
    double End_time;                 //服务结束的时间
    double turnroundTime;   //周转时间
    double  weightedTurnaroundTime;//带权周转时间
    double Priority;                 //优先权,这里面的优先级权是不能修改的!!!
    bool operator < (const ProcessNP& a)const
    {

        if (Priority == a.Priority)
            return Arrival_time > a.Arrival_time;  //在Priority相同的前提下,到达时间小(即到达最早的)优先出队
        return Priority < a.Priority;   //Priority大的优先出队   优先级大的在堆顶
    }

}processNP[MAXN];   //结构体数组

struct Process
{
    int pos;                          //代表第几个输入的进程
    char Process_name[50];            //进程名字,默认最长长度占用50字符
    double Arrival_time;             //进程到达时间
    double Service_time;             //服务时间       进程所需要的时间
    double Start_time;               //服务开始时间
    double End_time;                 //服务结束的时间
    double turnroundTime;   //周转时间
    double  weightedTurnaroundTime;//带权周转时间
    double Priority;                 //优先权,这里面的优先级权是不能修改的!!!
    bool operator < (const Process& a)const
    {
        if (Priority == a.Priority)
            return Arrival_time > a.Arrival_time;  //在Priority相同的前提下,到达时间小(即到达最早的)优先出队
        return Priority < a.Priority;   //Priority大的优先出队   优先级大的在堆顶
    }
}process[MAXN];   //结构体数组

//抢占式优先级的数据获取函数
void Init()
{
    printf("请输入进程的数量:");
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
    {
        cout << "请输入第" << i + 1 << "个进程的名字  到达时间  服务时间  优先权" << endl;
        scanf("%s", process[i].Process_name);
        scanf("%lf", &process[i].Arrival_time);
        scanf("%lf", &process[i].Service_time);
        scanf("%lf", &process[i].Priority);
        process[i].pos = i;
    }
}
//先来先服务和短进程的数据输入函数
void InitFS()
{
    printf("请输入进程的数量:");
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
    {
        cout << "请输入第" << i + 1 << "个进程的名字  到达时间  服务时间  优先权" << endl;
        scanf("%s", processFS[i].Process_name);
        scanf("%lf", &processFS[i].Arrival_time);
        scanf("%lf", &processFS[i].Service_time);
        scanf("%lf", &processFS[i].Priority);
        processFS[i].pos = i;
    }
};
//非抢占式优先级的数据输入函数
void InitNP()
{
    printf("请输入进程的数量:");
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
    {
        cout << "请输入第" << i + 1 << "个进程的名字  到达时间  服务时间  优先权" << endl;
        scanf("%s", processNP[i].Process_name);
        scanf("%lf", &processNP[i].Arrival_time);
        scanf("%lf", &processNP[i].Service_time);
        scanf("%lf", &processNP[i].Priority);
        processNP[i].pos = i;
    }
};

//抢占式优先级算法的优先级队列排序函数

bool cmp1(Process& a, Process& b)//优先级队列排序方式始终是先来的在队首
{
    return a.Arrival_time < b.Arrival_time;
};
//先来先服务和短进程优先排序函数
bool arrange(ProcessFS& a, ProcessFS& b)//优先级队列排序方式始终是先来的在队首
{
    return a.Arrival_time < b.Arrival_time;
};
//非抢占式优先级排序函数
bool arrangeNP(ProcessNP& a, ProcessNP& b)//优先级队列排序方式始终是先来的在队首
{
    return a.Arrival_time < b.Arrival_time;
};


void Solve_PPS()
{
    /*
    抢占式优先权调度:如果当前进程在执行时,如果后面出现了一个优先级更高的进程,我们就要暂时停止这个进程,先执行优先权高的程序!!
    */
    printf("抢占式优先权调度:\n");
    priority_queue<Process> que;
    sort(process, process + n, cmp1);  //根据到达时间进行排序,先到的先出队
    bool vis[MAXN];      //表示这个进程有没有在完成,完成使用true表示
    Process ans[MAXN]; //用于存放整个调度过程调度序列的进程
    double time = max(0.0, process[0].Arrival_time); int index = 0;   //取第一个进程的到达时间与0.0取最大值
    memset(vis, false, sizeof(vis));//对vis数组元素挨个拷贝为false,即让vis的元素初始值为false
    //首先将第一个放到优先队列中!
    que.push(process[0]); vis[process[0].pos] = 1;
    for (int i = 0; i < n; i++)
    {
        while (!que.empty())    
        {
            bool ok = false;
            Process temp = que.top(); que.pop();//将此刻优先级最高的进程赋予temp,然后在que中删除该进程
            //在temp的服务时间中,如果有新的优先权高的进程出现,那么就先执行优先权更高的进程,暂停这一段进程,并且更新这个进程所需要的时间等等
            temp.Start_time = time; temp.End_time = time + temp.Service_time;
            for (int j = 0; j < n; j++)
            {//在当前优先队列中的优先权永远是要小于当前执行的优先权的,那么我们只需要判断vis为false的就可以了!
                if (!vis[process[j].pos] && process[j].Priority > temp.Priority && process[j].Arrival_time < temp.End_time)//满足:进程尚未完成、其到达时间在正在执行进程结束之前、
                    //优先级大于正在执行进程的优先级  这写队列将处于队列前部的位置
                {
                    ok = true;
                    vis[process[j].pos] = 1;
                    que.push(process[j]);
                    temp.End_time = process[j].Arrival_time;//对被打断的正在执行的进程保存此刻结束时间
                    ans[index++] = temp;//计数index+1并且将阻塞进程()放入数组ans
                    temp.Service_time = time + temp.Service_time - temp.End_time;//更新当前的服务时间
                    que.push(temp);//继续放入后背队列que参与下一轮竞争
                    time = process[j].Arrival_time;  //记录此刻进程更换时间点
                    break;
                }
            }
            for (int j = 0; j < n; j++)//将这段时间内时间已经满足要求,但是优先权不是很高的添加到队列中!这些进程将处于队中的位置
            {
                if (!vis[process[j].pos] && process[j].Arrival_time <= temp.End_time)
                {
                    vis[process[j].pos] = 1;
                    que.push(process[j]);
                }
            }
            if (!ok)  //表示这个执行过程中没有打断的其它进程到来
            {
                time += temp.Service_time;
                ans[index++] = temp;   //ans[]结构体数组用来存放真实运行序列的进程
            }

        }
        bool flag = false; //判断是否所有的进程都已经完成
        for (int j = 0; j < n; j++)       //对于那些不会抢占当前进程又不在当前时间段的进程放入队尾
            if (!vis[process[j].pos])
            {
                vis[process[j].pos] = 1;
                que.push(process[j]);//将一个时间最靠前的添加到队列中
                time = process[j].Arrival_time;   //这里就要更新time了,因为这里的时间和上面的有些脱节!temp完整的运行时间已经过去
                flag = true; break;
            }
        if (!flag) break;
    }
    printf("进程的运行顺序为:\n");
    printf("%s", ans[0].Process_name);
    for (int i = 1; i < index; i++)
        printf("-->%s", ans[i].Process_name);
    Process shows[MAXN];  //用来输出好看的
    for (int i = 0; i < index; i++) {
        shows[ans[i].pos] = ans[i];
        shows[ans[i].pos].turnroundTime = shows[ans[i].pos].End_time - shows[ans[i].pos].Arrival_time;
        shows[ans[i].pos].weightedTurnaroundTime = shows[ans[i].pos].turnroundTime / shows[ans[i].pos].Service_time;
    }

    printf("\n");
    printf("name\tarrive_time\tservice_time\tstart_time\tend_time\n");
    for (int i = 0; i < n; i++)
        printf("%s\t%.2lf\t\t%.2lf\t\t%.2lf\t\t%.2lf\n", shows[i].Process_name, shows[i].Arrival_time, shows[i].Service_time, shows[i].Start_time, shows[i].End_time);
    //for(int i= 0;i < index;i ++)
       // cout<<ans[i].Process_name<<"\t"<<ans[i].Arrival_time<<"\t\t"<<ans[i].Service_time<<"\t\t"<<ans[i].Start_time<<"\t\t"<<ans[i].End_time<<endl;

    int k;
    float atTime = 0; // 平均周转时间 
    float AQTTime = 0; //平均带权周转时间 
    for (k = 0; k < n; k++)
    {
        atTime += shows[k].turnroundTime;
        AQTTime += shows[k].weightedTurnaroundTime;
    }
    atTime = atTime / n;
    AQTTime = AQTTime / n;
    printf("\n调用短进程优先算法的平均周转时间为:");
    printf("%.3f\n", atTime);
    printf("调用短进程优先算法的平均带权周转时间为:");
    printf("%.3f\n", AQTTime);
}

//先来先服务和短进程优先

void Solve_FCFS()
{
    /*
    先到先服务算法:是第一个排队,谁就先被执行,在执行过程中,不会中断他,当别人想要进入内存被执行,那么只能在后面排队
    */
    printf("先到先服务算法\n");
    sort(processFS, processFS + n, arrange);
    printf("进程的运行顺序为:\n");
    printf("%s", processFS[0].Process_name);
    for (int i = 1; i < n; i++)
        printf("-->%s", processFS[i].Process_name);
    printf("\n");
    double time = max(0.0, processFS[0].Arrival_time);//记录总的时间!
    for (int i = 0; i < n; i++)
    {
        processFS[i].Start_time = time;                           //更新开始时间
        processFS[i].End_time = time + processFS[i].Service_time;   //更新结束时间
        processFS[i].turnroundTime = processFS[i].End_time - processFS[i].Arrival_time; //更新周转时间
        processFS[i].weightedTurnaroundTime = processFS[i].turnroundTime / processFS[i].Service_time;  //更新带权周转时间
        time += processFS[i].Service_time;
        if (i != n - 1)   //当这时的结束时间小于下一个进程的到达时间的话,就要重新更新time
            time = max(time, processFS[i + 1].Arrival_time);
    }
    printf("name\tarrive_time\tservice_time\tstart_time\tend_time\tTA_time\tWTA_time\n");
    for (int i = 0; i < n; i++)
        printf("%s\t%.2lf\t\t%.2lf\t\t%.2lf\t\t%.2lf\t\t%.2lf\t%.2lf\n", processFS[i].Process_name, processFS[i].Arrival_time, processFS[i].Service_time, processFS[i].Start_time, processFS[i].End_time, processFS[i].turnroundTime, processFS[i].weightedTurnaroundTime);
    //    for(int i= 0;i < index;i ++)
    //        cout<<ans[i].Process_name<<"\t"<<ans[i].Arrival_time<<"\t\t"<<ans[i].Service_time<<"\t\t"<<ans[i].Start_time<<"\t\t"<<ans[i].End_time<<endl;


}
void Solve_SJF()
{
    /*
    最短作业优先调度算法:进程的时间长短作为优先级,进程时间越短,优先级越高
    寻找就绪队列中,进程时间最短的先执行,当存在多个长度相同的短作业时,按照提交时间的先后顺序进行调度
    */
    printf("最短作业优先调度算法:\n");
    priority_queue<ProcessFS> que;
    sort(processFS, processFS + n, arrange);
    bool vis[MAXN];      //表示这个进程有没有在完成,完成使用true表示
    ProcessFS ans[MAXN];
    double time = max(0.0, processFS[0].Arrival_time); int index = 0;
    memset(vis, false, sizeof(vis));
    //首先将第一个放到优先队列中!
    que.push(processFS[0]); vis[processFS[0].pos] = 1;
    for (int i = 0; i < n; i++)
    {
        while (!que.empty())
        {
            ProcessFS temp = que.top();   que.pop();
            temp.Start_time = time; temp.End_time = time + temp.Service_time; temp.turnroundTime = temp.End_time - temp.Arrival_time;//temp为当前(这个模型里)占用cpu进程
            temp.weightedTurnaroundTime = temp.turnroundTime / temp.Service_time;//整个循环是temp的整个周转时间为周期
            for (int j = 0; j < n; j++)
                if (!vis[processFS[j].pos] && processFS[j].Arrival_time <= temp.End_time)
                {
                    vis[processFS[j].pos] = 1;
                    que.push(processFS[j]);
                }
            time += temp.Service_time;       //这里面的时间都是有联系的,所以不用再次更新time ,因为占用cpu的进程不会被抢占
            ans[index++] = temp;             //将顺序存储到最终的答案序列中
        }
        bool flag = false; //判断是否所有的进程都已经完成
        for (int j = 0; j < n; j++)
            if (!vis[processFS[j].pos])
            {
                que.push(processFS[j]);//将一个时间最靠前的添加到队列中
                time = processFS[j].Arrival_time;   //这里就要更新time了,因为这里的时间和上面的有些脱节!
                flag = true; break;
            }
        if (!flag) break;
    }
    printf("进程的运行顺序为:\n");
    printf("%s", ans[0].Process_name);
    for (int i = 1; i < n; i++)
        printf("-->%s", ans[i].Process_name);
    printf("\n");
    printf("name\tarrive_time\tservice_time\tstart_time\tend_time\tTA_time\tWTA_time\n");
    for (int i = 0; i < n; i++)
        printf("%s\t%.2lf\t\t%.2lf\t\t%.2lf\t\t%.2lf\t\t%.2lf\t%.2lf\n", ans[i].Process_name, ans[i].Arrival_time, ans[i].Service_time, ans[i].Start_time, ans[i].End_time, ans[i].turnroundTime, ans[i].weightedTurnaroundTime);
    //    for(int i= 0;i < index;i ++)
    //        cout<<ans[i].Process_name<<"\t"<<ans[i].Arrival_time<<"\t\t"<<ans[i].Service_time<<"\t\t"<<ans[i].Start_time<<"\t\t"<<ans[i].End_time<<endl;
}

//非抢占式优先级调度

void Solve_FCFS1()
{
    /*
    先到先服务算法:是第一个排队,谁就先被执行,在执行过程中,不会中断他,当别人想要进入内存被执行,那么只能在后面排队
    */
    printf("先到先服务算法\n");
    sort(processNP, processNP + n, arrangeNP);
    printf("进程的运行顺序为:\n");
    printf("%s", processNP[0].Process_name);
    for (int i = 1; i < n; i++)
        printf("-->%s", processNP[i].Process_name);
    printf("\n");
    double time = max(0.0, processNP[0].Arrival_time);//记录总的时间!
    for (int i = 0; i < n; i++)
    {
        processNP[i].Start_time = time;                           //更新开始时间
        processNP[i].End_time = time + processNP[i].Service_time;   //更新结束时间
        processNP[i].turnroundTime = processNP[i].End_time - processNP[i].Arrival_time; //更新周转时间
        processNP[i].weightedTurnaroundTime = processNP[i].turnroundTime / processNP[i].Service_time;  //更新带权周转时间
        time += processNP[i].Service_time;
        if (i != n - 1)   //当这时的结束时间小于下一个进程的到达时间的话,就要重新更新time
            time = max(time, processNP[i + 1].Arrival_time);
    }
    printf("name\tarrive_time\tservice_time\tstart_time\tend_time\tTA_time\tWTA_time\n");
    for (int i = 0; i < n; i++)
        printf("%s\t%.2lf\t\t%.2lf\t\t%.2lf\t\t%.2lf\t\t%.2lf\t%.2lf\n", processNP[i].Process_name, processNP[i].Arrival_time, processNP[i].Service_time, processNP[i].Start_time, processNP[i].End_time, processNP[i].turnroundTime, processNP[i].weightedTurnaroundTime);
    //    for(int i= 0;i < index;i ++)
    //        cout<<ans[i].Process_name<<"\t"<<ans[i].Arrival_time<<"\t\t"<<ans[i].Service_time<<"\t\t"<<ans[i].Start_time<<"\t\t"<<ans[i].End_time<<endl;


}
void Solve_SJF1()
{
    /*
    最短作业优先调度算法:进程的时间长短作为优先级,进程时间越短,优先级越高
    寻找就绪队列中,进程时间最短的先执行,当存在多个长度相同的短作业时,按照提交时间的先后顺序进行调度
    */
    printf("非抢占式优先级调度算法:\n");
    priority_queue<ProcessNP> que;
    sort(processNP, processNP + n, arrangeNP);
    bool vis[MAXN];      //表示这个进程有没有在完成,完成使用true表示
    ProcessNP ans[MAXN];
    double time = max(0.0, processNP[0].Arrival_time); int index = 0;
    memset(vis, false, sizeof(vis));
    //首先将第一个放到优先队列中!
    que.push(processNP[0]); vis[processNP[0].pos] = 1;
    for (int i = 0; i < n; i++)
    {
        while (!que.empty())
        {
            ProcessNP temp = que.top();   que.pop();
            temp.Start_time = time; temp.End_time = time + temp.Service_time; temp.turnroundTime = temp.End_time - temp.Arrival_time;//temp为当前(这个模型里)占用cpu进程
            temp.weightedTurnaroundTime = temp.turnroundTime / temp.Service_time;//整个循环是temp的整个周转时间为周期
            for (int j = 0; j < n; j++)
                if (!vis[processNP[j].pos] && processNP[j].Arrival_time <= temp.End_time)
                {
                    vis[processNP[j].pos] = 1;
                    que.push(processNP[j]);
                }
            time += temp.Service_time;       //这里面的时间都是有联系的,所以不用再次更新time ,因为占用cpu的进程不会被抢占
            ans[index++] = temp;             //将顺序存储到最终的答案序列中
        }
        bool flag = false; //判断是否所有的进程都已经完成
        for (int j = 0; j < n; j++)
            if (!vis[processNP[j].pos])
            {
                que.push(processNP[j]);//将一个时间最靠前的添加到队列中
                time = processNP[j].Arrival_time;   //这里就要更新time了,因为这里的时间和上面的有些脱节!
                flag = true; break;
            }
        if (!flag) break;
    }
    printf("进程的运行顺序为:\n");
    printf("%s", ans[0].Process_name);
    for (int i = 1; i < n; i++)
        printf("-->%s", ans[i].Process_name);
     printf("\n");
    printf("name\tarrive_time\tservice_time\tstart_time\tend_time\tTA_time\tWTA_time\n");
    for (int i = 0; i < n; i++)
        printf("%s\t%.2lf\t\t%.2lf\t\t%.2lf\t\t%.2lf\t\t%.2lf\t%.2lf\n", ans[i].Process_name, ans[i].Arrival_time, ans[i].Service_time, ans[i].Start_time, ans[i].End_time, ans[i].turnroundTime, ans[i].weightedTurnaroundTime);
    //    for(int i= 0;i < index;i ++)
    //        cout<<ans[i].Process_name<<"\t"<<ans[i].Arrival_time<<"\t\t"<<ans[i].Service_time<<"\t\t"<<ans[i].Start_time<<"\t\t"<<ans[i].End_time<<endl;
}







int main()
{    

    int select = 1;
    while (select)
    {
        cout << "******************************************\n";
        cout << "*****1.******* 先来先服务算法及短作业优先 ************\n";
        cout << "*****2.********  静态非抢占优先级 ************\n";
        cout << "*****3.****  静态抢占优先级*********\n";
        cout << "*****0.**********退出*********************\n";

        cout << "请选择:> ";
        cin >> select;
        switch (select)
        {
        case 1:


            InitFS();
            Solve_FCFS();
            Solve_SJF();

            break;
        
        case 2:
            InitNP();
            Solve_FCFS1();
            Solve_SJF1();
            break;
        case 3:
            Init();
            Solve_PPS();
            break;
        default:
            break;

        }
    }
    return 0;

   
  
}

/*
5
1 1 10 80
2 11 15 20
3 21 10 50
4 31 10 120
5 41 10 100
3
A 0 5 1
B 2 2 2
C 3 4 3
*/

本文来自https://blog.csdn.net/li1615882553/article/details/80553945
我只是进行了部分整合和一点点添加和亿点点注释
还是要膜拜这位大佬

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值