设计一个按优先数调度算法实现处理器调度的进程

实验目的:在采用多道程序设计的系统中,往往有若干个进程同时处于就绪状态。当就绪状态进程 个数大于处理器数时,就必须依照某种策略来决定哪些进程优先占用处理器。本实验模拟在 单处理器情况下处理器调度,帮助学生加深了解处理器调度的工作。

题目:设计一个按优先数调度算法实现处理器调度的进程。

注:代码网上较多,我适当修改以符合我们老师的题目要求。

编程语言:C/C++ 

编译环境:Vs code

运行截图:

代码如下: 

// 操作系统实验一:按优先数调度算法实现处理器调度的进程。
// 优先数越大,优先级越高!
// 编译环境: Vs code

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <ctime>
#include <string>
#include <stdlib.h>
using namespace std;
// 定义进程控制块
struct PCB
{
    string name;         // 进程名
    PCB *next;           // 链接指针
    int arrive_time = 0; // 到达时间
    int priority = 0;    // 进程的优先级
    int run_time = 0;    // 预计运行时间
    string status;       // 进程状态
} head;

PCB *runing = new PCB;      // 指向正在运行的进程的指针
PCB *runing_last = new PCB; //指向正在运行的进程的上一个进程的指针
int currentTime = 0;        // 系统时间

PCB *init()
{ //初始化创建进程列表
    PCB *head = new PCB;
    PCB *end, *normal;
    int processNumber; // 进程的数目
    srand((unsigned)time(NULL));
    processNumber = 5;
    end = head;
    end->next = NULL;
    int i = 1;
    while (processNumber)
    {
        normal = new PCB;
        normal->name = 'P' + std::to_string(i); // 初始化进程名
        normal->arrive_time = rand() % 10 + 1;  // 进程到达时间随机初始化为1-10
        normal->priority = rand() % 5 + 10;     // 进程优先级随机初始化为10-15
        normal->run_time = rand() % 10 + 1;     // 进程预计运行时间随机初始化为1-10
        normal->status = "Ready";               // 设置进程状态
        end->next = normal;                     // 将新的进程放在尾节点的进程后面
        end = normal;                           // 新的进程成为尾进程
        processNumber--;                        // 自减,用来计数
        i++;                                    // 用来起名,保证每一个进程名不同
    }
    end->next = NULL; // 创建完成之后,将尾节点的下一个节点置为空
    PCB *p;
    p = head; // 将头节点传递给p指针
    cout << "初始进程队列:" << endl;
    cout << "进程名" << '\t' << "到达时间" << '\t' << "优先数" << '\t' << '\t' << "需要运行时间" << '\t' << "进程状态" << endl;
    while (p->next != NULL)
    { // 输出初始化生成的进程数据
        p = p->next;
        cout << p->name << '\t' << ' ' << p->arrive_time << '\t' << '\t' << p->priority << '\t' << '\t' << p->run_time << '\t' << '\t' << p->status << endl;
    }
    cout << "--------------------------This is the dividing line.---------------------------" << endl;
    return head; // 返回头指针
}

PCB *Sort(PCB *head) // 按priority进行排序
{
    int i, count = 0, num; // count记录链表结点的个数,num进行内层循环,
    PCB *p, *q, *tail;     //创建三个指针,进行冒泡排序
    p = head;
    while (p->next != NULL) //计算出结点的个数
    {
        count++; //注释①
        p = p->next;
    }
    for (i = 0; i < count - 1; i++) //外层循环,跟数组冒泡排序一样
    {
        num = count - i - 1; //记录内层循环需要的次数,跟数组冒泡排序一样,
        q = head->next;      //令q指向第一个结点
        p = q->next;         //令p指向后一个结点
        tail = head;         //让tail始终指向q前一个结点,方便交换,也方便与进行下一步操作
        while (num--)        //内层循环 次数跟数组冒泡排序一样
        {
            if (q->priority < p->priority) //如果该结点的值大于后一个结点,则交换
            {
                q->next = p->next;
                p->next = q;
                tail->next = p;
            }
            tail = tail->next;
            q = tail->next;
            p = q->next;
        }
    }
    return head;
}

void showProgressCondition(PCB *head)
{
    PCB *p = head; // 将头指针传给p指针
    if (p->next == NULL)
    { // p指针指向的下一个节点为空则代表链表为空,
        cout << "就绪队列中已经没有进程了!";
    }
    else
    {
        cout << "运行完成后就绪队列中的情况:" << endl;
        cout << "进程名" << '\t' << "到达时间" << '\t' << "优先数" << '\t' << '\t' << "需要运行时间" << '\t' << "进程状态" << endl;
        while (p->next != NULL)
        {
            p = p->next;
            if (p->arrive_time <= currentTime)
                cout << p->name << '\t' << ' ' << p->arrive_time << '\t' << '\t' << p->priority << '\t' << '\t' << p->run_time << '\t' << '\t' << p->status << endl;
        }
        cout << "--------------------------This is the dividing line.---------------------------" << endl;
    }
}

int priorityScheduling(PCB *head)
{
    currentTime++;                                              // currentTime自增,代表系统时间加一
    head = Sort(head);                                          // 排序
    for (PCB *p = head->next, *q = head; p; q = p, p = p->next) // 选取队列里第一个已到达的进程
    {
        if (p->arrive_time <= currentTime)
        {
            runing = p;
            runing_last = q;
            break;
        }
    }

    cout << "当前的时间为:" << currentTime << endl; //输出当前系统时间
    if (runing != NULL)
    { // 如果当前运行进程指针不为空,则代表就绪列表中有进程,可以进行输出
        cout << "当前运行的进程为:" << runing->name << "进程!" << endl;
        runing->priority--;         // 优先级数减一
        runing->run_time--;         // 预计运行时间减一
        runing->status = "Running"; // 状态变为运行态
        if (runing->run_time == 0)
        {
            // 调用函数,输出当前就绪队列中的情况
            cout << "进程" << runing->name << "已经运行完毕" << endl;
            runing->status = "End"; // 置进程的状态为完成态
            showProgressCondition(head);
            runing_last->next = runing->next; //从链表中删除该节点
            delete runing;                    //释放内存
            runing = NULL;                    // 节点删除之后,把当前最高优先级指针置为空
        }
        else
        {
            showProgressCondition(head);
            runing->status = "Ready"; // 如果没运行完成,则把进程的状态切换回就绪态,
        }
    }
    else
    { // 就绪队列中没有进程
        cout << "当前就绪列表无进程!" << endl;
    }
    return 0; //返回0
}

int main()
{
    int choose = 0;
    string select;
    bool runForAll = false;
    runing = NULL; // 一开始把当前最高优先级指针置空
    PCB *head;     // 声明指针
    head = init(); // 创建链表,用指针接受返回的头指针
    while (head->next != NULL)
    {                             // 利用循环,一直到链表中的进程全部退出链表才会结束循环
        priorityScheduling(head); // 调用函数,进行优先级调度
        if (!runForAll)
        {
            cout << "请输入数字或字母以继续,或输入“exit”退出,输入“all”直接运行结束。" << endl;
            cin >> select;
            if (select == "exit")
                break;
            else if (select == "all")
                runForAll = true;
        }
    }
    return 0;
}

  • 9
    点赞
  • 129
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

I_love_hanser_QAQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值