五种进程调度算法C++代码实现(FCFS、SJF、Priority、SRTF,Round Robin)

2023-05-16

说明:

1、假设有只两种状态,就绪状态和结束状态。进程的初始状态都为就绪状态。

2、每次运行所设计的处理器调度程序调度进程之前,为每个进程随机生成它的要求运行时间。

3、模拟处理器调度,被选中的进程并不实际启动运行,而是执行已运行时间+1来模拟进程的一次

运行,表示进程已经运行过一个单位时间

主要算法的流程图。

1、非抢占式(包括FCFS,SJF,Priority):

2、抢占式(包括SRTF):

3、轮转调度(包括Round_Robin):

1、数据结构:

class Process_Control_Block//进程控制单元类,用于存储进程信息

class PCB_LIST//循环链表类,用于存储和处理事件队列

enum PCB_State {READY, FINISH}; //进程的两种状态,就绪状态和结束状态

2、符号说明:

using PCB = Process_Control_Block//将PCB定义为Pross_Control_Block的别名

2、头文件:

#include <iostream>
#include<string>
#include <cstdlib>
#include<ctime> //srand()要用
#include <iomanip> //setw()要用
using namespace std;

具体声明:

//进程控制单元类

class Process_Control_Block {

public:

    string name;  //进程名

    int arriveTime;  //到达时间

    int needTime; //要求运行时间

    int remainTime; //剩余运行时间

    int runTime; //已运行时间

    int beginTime; //开始时间

    bool isFirstExe; //判断是否第一次执行

    int endTime; //结束时间

    int priority;  //作业优先级

    int turnaroundTime; //轮转时间

    PCB_State state;  //进程状态类型

    Process_Control_Block* next; //指向下一个的指针

    Process_Control_Block();//无参构造

    Process_Control_Block(string pcb_name, int pcb_atime, int pcb_priority);//带参构造

    Process_Control_Block(const PCB* sour);//拷贝构造

    void showPCB(); //打印PCB信息

};

//用于存储进程队列的循环链表类

class PCB_LIST

public:

    PCB* head;  //表头结点

    PCB_LIST() {

        head = new PCB();

        head->next = head;  //初始时头结点的下一个还是头结点

    }

    void InsertByArriveTime(PCB* pcb); //按到达时间插入

    void InsertByNeedTime(PCB* pcb);  //按进程所需时间插入

    void InsertByEndTime(PCB* pcb);  //按进程结束时间插入

    void InsertByPriority(PCB* pcb);  //按进程优先级插入

    void InsertByRemainTime(PCB* pcb);  //按进程剩余时间插入

    void InsertAtTail(PCB* pcb);  //插入到队列最后

    bool deleteByName(string pcb_name); //根据进程名删除进程

    bool updata(PCB* pcb);//更新某进程的状态

    void showAll(); //打印全部进程状态

    bool isEmpty();  //判断链表中所有进程任务都已完成

    int getSize(); //获得队列长度

    PCB* getTail();//获得队列中最后一个PCB

    double getAverTurnTime(); //获得平均轮转时间

    double getAverWaitTime();//计算平均等待时间

double getThroughput();//获得吞吐量

double getResponseTime(); //获得平均响应时间

    void clear_list();//清空队列

    PCB* FetchFirstPCB(); //获取队列中第一个PCB

};

(其中函数具体实现代码见附录)

3、程序清单及注释:

函数声明:

//打印进程信息表头                             

void print_header();

//计算并打印进程总体信息(如吞吐量,CPU利用率等)

void showInfo(PCB_LIST* finishQueue);

//输入作业信息,按发生时间插入队列

void wirite_list(PCB_LIST* pcb_list);

//PCB的拷贝方法(不改变指针指向,只改变内容)

void CopyPCB(PCB* dest, const PCB* sour);

//最短作业时间优先

void SJF(PCB_LIST* pcb_list);

//先来先服务

void FCFS(PCB_LIST* pcb_list);

//最短剩余时间优先

void SRTF(PCB_LIST* pcb_list);

//按优先级,运行一个时间片后下调优先级别(时间片长度为2)

void Priority(PCB_LIST* pcb_list);

//时间片轮转(时间片大小为2)

void Round_Robin(PCB_LIST* pcb_list);

具体实现:

//最短作业时间优先

void SJF(PCB_LIST* pcb_list) {

    int currentTime = 0;            //当前时间

    bool isCPU_Busy = false;        //CPU忙碌状态

    PCB_LIST* readyQueue = new PCB_LIST(); //就绪队列

    PCB_LIST* finishQueue = new PCB_LIST(); //结束队列

    PCB* run_pcb = pcb_list->FetchFirstPCB(); //正在运行的pcb

    PCB* arrived_pcb = run_pcb; //当前已经到达的pcb

    while (!pcb_list->isEmpty()) {  //判断事件队列是否为空

        while (arrived_pcb != pcb_list->head && currentTime >= arrived_pcb->arriveTime) {

            if (isCPU_Busy) { //如CPU忙碌,则按作业时间插入就绪队列

                readyQueue->InsertByNeedTime(arrived_pcb);

            }

            else {

                run_pcb = arrived_pcb;   //如CPU空闲,将到达的pcb设为正在运行的pcb

            }

            arrived_pcb = arrived_pcb->next;

        }

        if (run_pcb->state == PCB_State::READY) {

            isCPU_Busy = true;

            if (run_pcb->isFirstExe) { //第一次执行记录开始时间

                run_pcb->beginTime = currentTime;  //进程发生时间为当前时间

                run_pcb->isFirstExe = false;

            }

            run_pcb->runTime = currentTime - run_pcb->beginTime;  //已运行时间

            run_pcb->remainTime = run_pcb->needTime - run_pcb->runTime; //剩余运行时间

            if (run_pcb->runTime == run_pcb->needTime) {

                run_pcb->endTime = currentTime; //设定结束时间

                run_pcb->turnaroundTime = run_pcb->endTime - run_pcb->arriveTime;

                run_pcb->state = PCB_State::FINISH; //状态改为结束

                finishQueue->InsertByEndTime(run_pcb);  //按结束时间插入结束队列

            }

            currentTime++;

        }

        if (run_pcb->state == PCB_State::FINISH) {

            cout << "时间:" << currentTime - 1 << endl;

            cout << "此时运行的进程:" << endl;

            print_header();

            run_pcb->showPCB();

            cout << "结束的进程:" << endl;

            print_header();

            finishQueue->showAll();

           

            string finish_name = run_pcb->name; //已结束进程的名字

            isCPU_Busy = false;

            readyQueue->deleteByName(finish_name);

            if (!readyQueue->isEmpty()) {

                run_pcb = readyQueue->FetchFirstPCB();  //取就绪队列的第一个

            }

            pcb_list->deleteByName(finish_name);

            cout << "就绪队列状态:" << endl;

            print_header();

            readyQueue->showAll();

            cout << endl;

        }

    }

    showInfo(finishQueue);  //打印总体信息

}

//先来先服务

void FCFS(PCB_LIST* pcb_list) {

    int currentTime = 0;            //当前时间

    bool isCPU_Busy = false;        //CPU忙碌状态

    PCB_LIST* readyQueue = new PCB_LIST(); //就绪队列

    PCB_LIST* finishQueue = new PCB_LIST(); //结束队列

    PCB* run_pcb = pcb_list->FetchFirstPCB(); //取最先到达的进程运行

    PCB* arrived_pcb = run_pcb; //当前已经到达的pcb

    while (!pcb_list->isEmpty()) {  //判断事件队列是否为空

        while (arrived_pcb != pcb_list->head) {

            readyQueue->InsertByArriveTime(arrived_pcb);

            arrived_pcb = arrived_pcb->next;

        }

        if (run_pcb->state == PCB_State::READY) {

            isCPU_Busy = true;

            if (run_pcb->arriveTime > currentTime) {

                currentTime = run_pcb->arriveTime;

            }

            run_pcb->beginTime = currentTime;

            run_pcb->endTime = run_pcb->beginTime + run_pcb->needTime;

            run_pcb->runTime = run_pcb->needTime;

            currentTime = run_pcb->endTime;

            run_pcb->remainTime = 0;

            run_pcb->turnaroundTime = run_pcb->endTime - run_pcb->arriveTime;

            run_pcb->state = PCB_State::FINISH;

            finishQueue->InsertByEndTime(run_pcb);

        }

        if (run_pcb->state == PCB_State::FINISH) {

            cout << "时间:" << currentTime - 1 << endl;

            cout << "在运行的进程:" << endl;

            print_header();

            run_pcb->showPCB();

            cout << "已完成的线程:" << endl;

            print_header();

            finishQueue->showAll();

            string finish_name = run_pcb->name; //已结束进程的名字

            isCPU_Busy = false;

            readyQueue->deleteByName(finish_name);

            if (!readyQueue->isEmpty()) {

                run_pcb = readyQueue->FetchFirstPCB();  //取就绪队列的第一个开始运行

            }

            pcb_list->deleteByName(finish_name);

            cout << "就绪队列状态:" << endl;

            print_header();

            readyQueue->showAll();

            cout << endl;

        }

    }

    showInfo(finishQueue);  //打印总体信息

}

//按优先级(每次运行后优先级不变)

void Priority(PCB_LIST* pcb_list)

{

    int currentTime = 0;            //当前时间

    bool isCPU_Busy = false;        //CPU忙碌状态

    PCB_LIST* readyQueue = new PCB_LIST(); //就绪队列

    PCB_LIST* finishQueue = new PCB_LIST(); //结束队列

    PCB* run_pcb = pcb_list->FetchFirstPCB(); //正在运行的pcb

    PCB* arrived_pcb = run_pcb; //当前已经到达的pcb

    while (!pcb_list->isEmpty()) { //判断事件队列是否为空

        while (arrived_pcb != pcb_list->head && currentTime >= arrived_pcb->arriveTime) {

            if (isCPU_Busy) { //如CPU忙碌,则按作业优先级插入就绪队列

                readyQueue->InsertByPriority(arrived_pcb);

            }

            else {

                run_pcb = arrived_pcb;   //如CPU空闲,将到达的pcb设为正在运行的pcb

            }

            arrived_pcb = arrived_pcb->next;

        }

        if (run_pcb->state == PCB_State::READY) {

            isCPU_Busy = true;

            if (run_pcb->isFirstExe) { //第一次执行记录开始时间

                run_pcb->beginTime = currentTime;  //进程发生时间为当前时间

                run_pcb->isFirstExe = false;

            }

            run_pcb->runTime = currentTime - run_pcb->beginTime;  //已运行时间

            run_pcb->remainTime = run_pcb->needTime - run_pcb->runTime; //剩余运行时间

            if (run_pcb->runTime == run_pcb->needTime) {

                run_pcb->endTime = currentTime; //设定结束时间

                run_pcb->turnaroundTime = run_pcb->endTime - run_pcb->arriveTime; //计算轮转时间

                run_pcb->state = PCB_State::FINISH; //状态改为结束

                finishQueue->InsertByEndTime(run_pcb);  //按结束时间插入结束队列

            }

            currentTime++;

        }

        if (run_pcb->state == PCB_State::FINISH) {

            cout << "时间:" << currentTime - 1 << endl;

            cout << "在运行的进程:" << endl;

            print_header();

            run_pcb->showPCB();

            cout << "已完成的进程:" << endl;

            print_header();

            finishQueue->showAll();

            string finish_name = run_pcb->name; //已结束进程的名字

            isCPU_Busy = false;

            readyQueue->deleteByName(finish_name);

            if (!readyQueue->isEmpty()) {

                run_pcb = readyQueue->FetchFirstPCB();  //取就绪队列的第一个

            }

            pcb_list->deleteByName(finish_name);

            cout << "就绪队列状态:" << endl;

            print_header();

            readyQueue->showAll();

            cout << endl;

        }

    }

    showInfo(finishQueue);  //打印总体信息

}

//按优先级,运行一个时间片后下调优先级别(时间片长度为2)

void Priority_2(PCB_LIST* pcb_list) {

    int currentTime = 0;            //当前时间

    bool isCPU_Busy = false;        //CPU忙碌状态

    PCB_LIST* readyQueue = new PCB_LIST(); //就绪队列

    PCB_LIST* finishQueue = new PCB_LIST(); //结束队列

    int timeSlice = 2; //时间片大小为2

    PCB* run_pcb = pcb_list->FetchFirstPCB(); //正在运行的pcb(最先到达的进程)

    PCB* arrived_pcb = run_pcb; //当前已经到达的pcb

    while (!pcb_list->isEmpty()) {//判断事件队列是否为空

        while (arrived_pcb != pcb_list->head && currentTime >= arrived_pcb->arriveTime) { //如当前时间已超过到达时间,则插入就绪队列

            if (isCPU_Busy) { //如CPU忙碌,则按到达时间插入就绪队列末尾

                cout << "就绪队列状态:" << endl;

                readyQueue->showAll();

                run_pcb = readyQueue->FetchFirstPCB();

            }

            else {

                run_pcb = arrived_pcb;   //如CPU空闲,将到达的pcb设为正在运行的pcb

            }

            arrived_pcb = arrived_pcb->next; //到达的pcb指向下一个

        }

        if (!readyQueue->isEmpty())

            run_pcb = readyQueue->FetchFirstPCB();  //取就绪队列的第一个

        else//如就绪队列为空,就直接取事件队列第一个,并将当前时间设为它的到达时间

            run_pcb = pcb_list->FetchFirstPCB();

        }

        if (run_pcb->state == PCB_State::READY) {

            isCPU_Busy = true;

            if (run_pcb->isFirstExe) {

                run_pcb->beginTime = currentTime;  //进程发生时间为当前时间

                run_pcb->isFirstExe = false;

            }

            currentTime += timeSlice;  //每次加时间片的长度

            run_pcb->runTime += timeSlice; //已运行时间+时间片长度

            run_pcb->remainTime = run_pcb->needTime - run_pcb->runTime; //计算剩余时间

            run_pcb->priority += 2;

           

            if (run_pcb->remainTime <= 0) {

                run_pcb->endTime = currentTime + run_pcb->remainTime; //设定结束时间(减去小于0的部分)

                run_pcb->turnaroundTime = run_pcb->endTime - run_pcb->arriveTime;  //计算轮转时间

                run_pcb->state = PCB_State::FINISH; //状态改为结束

                run_pcb->remainTime = 0; //保证剩余时间不是负数

                finishQueue->InsertByEndTime(run_pcb);  //按结束时间插入结束队列

            }

            pcb_list->updata(run_pcb);    //更新事件队列中的信息

            PCB* temp = new PCB(run_pcb);

            readyQueue->deleteByName(run_pcb->name); //删除原队列中正在运行的进程

            if (temp->state == PCB_State::READY)//如没有结束

                readyQueue->InsertByPriority(temp);  //重新插入就绪队列尾部

            while (arrived_pcb != pcb_list->head && arrived_pcb->arriveTime <= currentTime) { //查看此时有无到达的队列

                readyQueue->InsertByPriority(arrived_pcb); //插入到达的进程

                arrived_pcb = arrived_pcb->next; //到达的pcb指向下一个

            }

            if (temp->state != PCB_State::READY) { //如进程结束了就打印信息

                cout << "时间:" << currentTime << endl;

                cout << "在该时间片运行进程:" << endl;

                print_header();

                temp->showPCB();

                cout << "结束的进程:" << endl;

                print_header();

                finishQueue->showAll();

                cout << "运行结束后就绪队列状态:" << endl;

                print_header();

                readyQueue->showAll();

                cout << endl;

            }

        }

        if (run_pcb->state == PCB_State::FINISH) {

            string finish_name = run_pcb->name; //已结束进程的名字

            isCPU_Busy = false;

            readyQueue->deleteByName(finish_name);

            if (!readyQueue->isEmpty()) {

                run_pcb = readyQueue->FetchFirstPCB();  //取就绪队列的第一个

            }

            pcb_list->deleteByName(finish_name);

        }

    }

    showInfo(finishQueue);  //打印总体信息

}

//最短剩余时间优先

void SRTF(PCB_LIST* pcb_list) {

    int currentTime = 0;            //当前时间

    bool isCPU_Busy = false;        //CPU忙碌状态

    PCB_LIST* readyQueue = new PCB_LIST(); //就绪队列

    PCB_LIST* finishQueue = new PCB_LIST(); //结束队列

    PCB* run_pcb = pcb_list->FetchFirstPCB(); //正在运行的pcb

    PCB* arrived_pcb = run_pcb; //当前已经到达的pcb

    while (!pcb_list->isEmpty()) {//判断事件队列是否为空

        while (arrived_pcb != pcb_list->head && currentTime >= arrived_pcb->arriveTime) { //如当前时间已超过到达时间,则插入就绪队列

            if (isCPU_Busy) { //如CPU忙碌,则按作业剩余时间插入就绪队列

                readyQueue->InsertByRemainTime(arrived_pcb);  //将新进入的进程插入就绪队列

                if (arrived_pcb->remainTime <= run_pcb->remainTime) {  //新进入的进程剩余时间小于正在运行的进程,则终止正在运行的进程,重新插入就绪队列

                    PCB* re_run = new PCB(run_pcb);

                    readyQueue->deleteByName(run_pcb->name); //删除原队列中的数据

                    readyQueue->InsertByRemainTime(re_run);  //重新插入队列中

                    run_pcb = readyQueue->FetchFirstPCB(); //新的运行进程为就绪队列最前的进程

                }

            }

            else {

                run_pcb = arrived_pcb;   //如CPU空闲,将到达的pcb设为正在运行的pcb

            }

            arrived_pcb = arrived_pcb->next;

       }

        if (run_pcb->state == PCB_State::READY) {

            isCPU_Busy = true;

            if (run_pcb->isFirstExe) {

                run_pcb->beginTime = currentTime;  //进程发生时间为当前时间

                run_pcb->isFirstExe = false;

            }

            run_pcb->runTime++; //已运行时间+1

            run_pcb->remainTime = run_pcb->needTime - run_pcb->runTime; //计算剩余时间

            if (run_pcb->remainTime == 0) {

                run_pcb->endTime = currentTime; //设定结束时间

                run_pcb->turnaroundTime = run_pcb->endTime - run_pcb->arriveTime;  //计算轮转时间

                run_pcb->state = PCB_State::FINISH; //状态改为结束

                finishQueue->InsertByEndTime(run_pcb);  //按结束时间插入结束队列

            }

            currentTime++;

           

       }

        if (run_pcb->state == PCB_State::FINISH) {

            cout << "时间:" << currentTime - 1 << endl;

            cout << "此时运行的进程:" << endl;

            print_header();

            run_pcb->showPCB();

            cout << "结束的进程:" << endl;

            print_header();

            finishQueue->showAll();

            string finish_name = run_pcb->name; //已结束进程的名字

            isCPU_Busy = false;

            readyQueue->deleteByName(finish_name);

            if (!readyQueue->isEmpty()) {

                run_pcb = readyQueue->FetchFirstPCB();  //取就绪队列的第一个

                isCPU_Busy = true;

            }

            pcb_list->deleteByName(finish_name);

            cout << "就绪队列状态:" << endl;

            print_header();

            readyQueue->showAll();

            cout << endl;

        }

    }

    showInfo(finishQueue);  //打印总体信息

}

//时间片轮转(时间片大小为2)

void Round_Robin(PCB_LIST* pcb_list) {

    int currentTime = 0;            //当前时间

    bool isCPU_Busy = false;        //CPU忙碌状态

    PCB_LIST* readyQueue = new PCB_LIST(); //就绪队列

    PCB_LIST* finishQueue = new PCB_LIST(); //结束队列

    int timeSlice = 2; //时间片大小为2

    PCB* run_pcb = pcb_list->FetchFirstPCB(); //正在运行的pcb(最先到达的进程)

    PCB* arrived_pcb = run_pcb; //当前已经到达的pcb

    while (!pcb_list->isEmpty()) {//判断事件队列是否为空

        while (arrived_pcb != pcb_list->head && currentTime >= arrived_pcb->arriveTime) { //如当前时间已超过到达时间,则插入就绪队列

            if (isCPU_Busy) { //如CPU忙碌,则按到达时间插入就绪队列末尾

                run_pcb = readyQueue->FetchFirstPCB();

            }

            else {

                run_pcb = arrived_pcb;   //如CPU空闲,将到达的pcb设为正在运行的pcb

            }

            arrived_pcb = arrived_pcb->next; //到达的pcb指向下一个

        }

        if (!readyQueue->isEmpty())

            run_pcb = readyQueue->FetchFirstPCB();  //取就绪队列的第一个

        else//如就绪队列为空,就直接取事件队列第一个,并将当前时间设为它的到达时间

            run_pcb = pcb_list->FetchFirstPCB();

        }

        if (run_pcb->state == PCB_State::READY) {

            isCPU_Busy = true;

            if (run_pcb->isFirstExe) {

                run_pcb->beginTime = currentTime;  //进程发生时间为当前时间

                run_pcb->isFirstExe = false;

            }

            currentTime += timeSlice;  //每次加时间片的长度

            run_pcb->runTime += timeSlice; //已运行时间+时间片长度

            run_pcb->remainTime = run_pcb->needTime - run_pcb->runTime; //计算剩余时间

            if (run_pcb->remainTime <= 0) {

                run_pcb->endTime = currentTime + run_pcb->remainTime; //设定结束时间(减去小于0的部分)

                run_pcb->turnaroundTime = run_pcb->endTime - run_pcb->arriveTime; //计算轮转时间

                run_pcb->state = PCB_State::FINISH; //状态改为结束

                run_pcb->remainTime = 0; //保证剩余时间不是负数

                finishQueue->InsertByEndTime(run_pcb);  //按结束时间插入结束队列

            }

            pcb_list->updata(run_pcb);  //每次更新时间队列中的信息

            PCB* temp = new PCB(run_pcb);

            readyQueue->deleteByName(run_pcb->name); //删除原队列中正在运行的进程

            if (temp->state == PCB_State::READY)//如没有结束

                readyQueue->InsertAtTail(temp);  //重新插入就绪队列尾部

            while (arrived_pcb != pcb_list->head && arrived_pcb->arriveTime <= currentTime) { //查看此时有无到达的队列

                readyQueue->InsertAtTail(arrived_pcb); //插入到达的进程

                arrived_pcb = arrived_pcb->next; //到达的pcb指向下一个

            }

            if (temp->state != PCB_State::READY) { //如进程结束了就打信息

                cout << "时间:" << currentTime << endl;

                cout << "在该时间片运行进程:" << endl;

                print_header();

                temp->showPCB();

                cout << "结束的进程:" << endl;

                print_header();

                finishQueue->showAll();

                cout << "运行结束后就绪队列状态:" << endl;

                print_header();

                readyQueue->showAll();

                cout << endl;

            }

        }

        if (run_pcb->state == PCB_State::FINISH) {

            string finish_name = run_pcb->name; //已结束进程的名字

            isCPU_Busy = false;

            readyQueue->deleteByName(finish_name);

            if (!readyQueue->isEmpty()) {

                run_pcb = readyQueue->FetchFirstPCB();  //取就绪队列的第一个

            }

            pcb_list->deleteByName(finish_name);

        }

    }

    showInfo(finishQueue);  //打印总体信息

}

//打印表头

void print_header() { 

    cout << setw(8) << "进程名" << setw(10) << "到达时间" << setw(10) << "所需时间" << setw(10) << "开始时间" << setw(10) << "结束时间" << setw(10)<<"运行时间" << setw(10) << "剩余时间" << setw(8) << "优先级" << endl;

}

//打印进程总体信息

void showInfo(PCB_LIST* finishQueue) {

    cout << "CPU Utilization: 100%" << endl;

    cout << "Throughput: " << finishQueue->getThroughput() << endl;

    cout << "Average turnaround time: " << finishQueue->getAverTurnTime() << endl;

    cout << "Average waiting time: " << finishQueue->getAverWaitTime() << endl;

    cout << "Response time: 0" << endl;

}

//输入作业信息,按发生时间插入队列

void wirite_list(PCB_LIST* pcb_list) { 

    pcb_list->InsertByArriveTime(new PCB("B", 2, 1));

    pcb_list->InsertByArriveTime(new PCB("A", 0, 1));

    pcb_list->InsertByArriveTime(new PCB("C", 5, 2));

    pcb_list->InsertByArriveTime(new PCB("D", 5, 1));

    pcb_list->InsertByArriveTime(new PCB("E", 12, 4));

    pcb_list->InsertByArriveTime(new PCB("F", 15, 2));

}

//PCB的拷贝方法(不改变指针指向,只改变内容)

void CopyPCB(PCB* dest, const PCB* sour) { 

    dest->arriveTime = sour->arriveTime;

    dest->name = sour->name;

    dest->needTime = sour->needTime;

    dest->priority = sour->priority;

    dest->remainTime = sour->remainTime;

    dest->runTime = sour->runTime;

    dest->beginTime = sour->beginTime;

    dest->state = sour->state;

    dest->endTime = sour->endTime;

    dest->isFirstExe = sour->isFirstExe;

    dest->turnaroundTime = sour->turnaroundTime;

}

主函数:

int main()

{

    PCB_LIST* pcb_list = new PCB_LIST(); //新建事件队列

    cout << "---------------SRTF---------------" << endl;

    wirite_list(pcb_list);

    SRTF(pcb_list);

    pcb_list->clear_list();

    cout << "---------------SJF---------------" << endl;

    wirite_list(pcb_list);

    SJF(pcb_list);

    pcb_list->clear_list();

    cout << "---------------FCFS---------------" << endl;

    wirite_list(pcb_list);

    FCFS(pcb_list);

    pcb_list->clear_list();

    cout << "---------------Priority---------------" << endl;

    wirite_list(pcb_list);

    Priority(pcb_list);

    pcb_list->clear_list();

    cout << "---------------Round_Robin---------------" << endl;

    wirite_list(pcb_list);

    Round_Robin(pcb_list);

    pcb_list->clear_list();

}

附录

循环链表类PCB_LIST及进程控制块类PCB函数实现代码:

1PCB类:

void Process_Control_Block::showPCB() {

    cout<< setw(8) << name << setw(10) << arriveTime  << setw(10)<< needTime << setw(10)  << beginTime << setw(10)  << endTime << setw(10) << runTime << setw(10) << remainTime << setw(8) << priority << endl;

}

//拷贝构造

Process_Control_Block::Process_Control_Block(const PCB* sour) {

    arriveTime = sour->arriveTime;

    name = sour->name;

    needTime = sour->needTime;

    priority = sour->priority;

    remainTime = sour->remainTime;

    runTime = sour->runTime;

    beginTime = sour->beginTime;

    state = sour->state;

    endTime = sour->endTime;

    turnaroundTime = sour->turnaroundTime;

    isFirstExe = sour->isFirstExe;

    next = NULL;

}

//无参构造

Process_Control_Block::Process_Control_Block() {

    needTime = 1 + rand() % 10;

    state = PCB_State::READY//状态设为就绪

    runTime = 0;  //已运行时间设为0

    beginTime = 0; //开始时间设为0

    endTime = 0;   //结束时间设为0

    remainTime = needTime; //时间等于所需时间

    isFirstExe = true//是第一次指行

    arriveTime = 0; //到达时间设为0

    priority = 0; //优先级设为0

    turnaroundTime = 0;  //轮转时间设为0

    next = NULL//初始的下一个事件为空

}

//带参构造

Process_Control_Block::Process_Control_Block(string pcb_name, int pcb_atime, int pcb_priority) {

    name = pcb_name;

    arriveTime = pcb_atime;

    priority = pcb_priority;

    needTime = 1 + rand() % 10;  //随机生成所需时间

    state = PCB_State::READY//状态设为就绪

    runTime = 0;  //已运行时间设为0

    beginTime = 0; //发生时间设为0

    endTime = 0;   //结束时间设为0

    turnaroundTime = 0; //轮转时间设为0

    isFirstExe = true//是第一次指行

    remainTime = needTime; //时间等于所需时间

    next = NULL//初始的下一个事件为空

}

2PCB_LIST类:

//获得平均响应时间

double PCB_LIST::getResponseTime() {

    PCB* p = head->next;

    double sum = 0;

    double n = getSize();

    if (p->next == head)

        return -1;

    while (p != head) {

        sum = sum + (p->beginTime - p->arriveTime);

        p = p->next;

    }

    return sum / n;

}

void PCB_LIST::clear_list() {

    PCB* p = head->next;

    while (p != head) {

        head->next = p->next;

        delete p;

        p = head->next;

    }

}

//获得吞吐量

double PCB_LIST::getThroughput() {

    if (!isEmpty()) {

        double sum_time = getTail()->endTime;

        double n = getSize();

        return n / sum_time;

    }

    return 0;

}

//计算平均等待时间

double PCB_LIST::getAverWaitTime() {

    PCB* p = head->next;

    double sum = 0;

    double n = getSize();

    if (p->next == head)

        return -1;

    while (p != head) {

        sum = sum + (p->endTime - p->arriveTime - p->runTime);

        p = p->next;

    }

    return sum / n;

}

//获得平均轮转时间

double PCB_LIST::getAverTurnTime() {

    PCB* p = head->next;

    double sum = 0;

    double n = getSize();

    if (p->next == head)

        return -1;

    while (p != head) {

        sum += p->turnaroundTime;

        p = p->next;

    }

    return sum / n;

}

//获得尾部结点

PCB* PCB_LIST::getTail() {

    PCB* p = head;

    if (p->next == head)

        return NULL;

    while (p->next != head) {

        p = p->next;

    }

    return p;

}

//获得队列长度

int PCB_LIST::getSize() {

    int cont = 0;

    PCB* p = head->next;

    while (p != head) {

        p = p->next;

        cont++;

    }

    return cont;

}

//插入到队列最后

void PCB_LIST::InsertAtTail(PCB* pcb) {

    PCB* p = head;

    PCB* new_pcb = new PCB(pcb);

    while (p->next != head) {

        p = p->next;

    }

    p->next = new_pcb;

    new_pcb->next = head;

}

//更新某进程的状态

bool PCB_LIST::updata(PCB* pcb) {

    PCB* p = head->next;

    if (p == head) {  //如为空返回

        return false;

    }

    while (p != head && p->name != pcb->name) {  //找到要删除结点的前一个

        p = p->next;

    }

    if (p == head) {  //如没找到,返回false

        return false;

    }

    CopyPCB(p, pcb);

    return true;

}

//按进程剩余时间插入

void PCB_LIST::InsertByRemainTime(PCB* pcb) {

    PCB* p = head;

    PCB* new_pcb = new PCB(pcb);

    while (p->next != head && p->next->remainTime < pcb->remainTime) {

        p = p->next;

    }

    if (p == head && head->next == head) {  //如链表中只有头结点

        head->next = new_pcb;

        new_pcb->next = head;

    }

    else if (p->next == head) {  //如果要插在最后

        p->next = new_pcb;

        new_pcb->next = head;

    }

    else//在中间插入

        PCB* q = p->next;

        p->next = new_pcb;

        new_pcb->next = q;

    }

}

//按进程优先级插入

void PCB_LIST::InsertByPriority(PCB* pcb) {

    PCB* p = head;

    PCB* new_pcb = new PCB(pcb);

    while (p->next != head && p->next->priority < pcb->priority) {

        p = p->next;

    }

    if (p == head && head->next == head) {  //如链表中只有头结点

        head->next = new_pcb;

        new_pcb->next = head;

    }

    else if (p->next == head) {  //如果要插在最后

        p->next = new_pcb;

        new_pcb->next = head;

    }

    else//在中间插入

        PCB* q = p->next;

        p->next = new_pcb;

        new_pcb->next = q;

    }

}

//按到达时间插入

void PCB_LIST::InsertByArriveTime(PCB* pcb) { 

    PCB* p = head;

    PCB* new_pcb = new PCB(pcb);

    while (p->next != head && p->next->arriveTime < pcb->arriveTime) {

        p = p->next;

    }

    if (p == head && head->next == head) {  //如链表中只有头结点

        head->next = new_pcb;

        new_pcb->next = head;

    }

    else if(p->next == head) {  //如果要插在最后

        p->next = new_pcb;

        new_pcb->next = head;

    }

    else//在中间插入

        PCB* q = p->next;

        p->next = new_pcb;

        new_pcb->next = q;

    }

}

//按进程所需时间插入

void PCB_LIST::InsertByNeedTime(PCB* pcb) { 

    PCB* p = head;

    PCB* new_pcb = new PCB(pcb);

    while (p->next != head && p->next->needTime < pcb->needTime) {

        p = p->next;

    }

    if (p == head && head->next == head) {  //如链表中只有头结点

        head->next = new_pcb;

        new_pcb->next = head;

    }

    else if (p->next == head) {  //如果要插在最后

        p->next = new_pcb;

        new_pcb->next = head;

    }

    else//在中间插入

        PCB* q = p->next;

        p->next = new_pcb;

        new_pcb->next = q;

    }

}

//按进程结束时间插入

void PCB_LIST::InsertByEndTime(PCB* pcb) {

    PCB* p = head->next;

    PCB* new_pcb = new PCB(pcb);

    while (p->next != head && p->next->endTime < pcb->endTime) {

        p = p->next;

    }

    if (p == head && head->next == head) {  //如链表中只有头结点

        head->next = new_pcb;

        new_pcb->next = head;

    }

    else if (p->next == head) {  //如果要插在最后

        p->next = new_pcb;

        new_pcb->next = head;

    }

    else//在中间插入

        PCB* q = p->next;

        p->next = new_pcb;

        new_pcb->next = q;

    }

}

//根据进程名删除进程

bool PCB_LIST::deleteByName(string pcb_name) {

    PCB* p = head;

    if (p->next == head) {  //如链表为空返回

        return false;

    }

    while (p->next != head && p->next->name != pcb_name) {  //找到要删除结点的前一个

        p = p->next;

    }

    if (p->next == head) {  //如没找到,返回false

        return false;

    }

    else {

        PCB* q = p->next;  //q为要删除结点

        p->next = q->next;

        delete q;

    }

    return true;

}

//打印全部进程状态

void PCB_LIST::showAll() { 

    PCB* p = head->next;

    while (p != head) {

        p->showPCB();

        p = p->next;

    }

}

//判断是否为空表

bool PCB_LIST::isEmpty() { 

    if (head->next == head)

        return true;

    return false;

}

//获取队列中第一个PCB

PCB* PCB_LIST::FetchFirstPCB() {

    if (head->next == head) 

        return NULL;

    return head->next;

}

运行截图:

1、测试数据:

2、运行结果

SRTF

 ②SJF:

FCFS

Priority

Round_Robin

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

五种进程调度算法C++代码实现(FCFS、SJF、Priority、SRTF,Round Robin) 的相关文章

  • Oracle 的 Round函数

    Round函数用法 xff1a 截取数字 格式如下 xff1a ROUND xff08 number decimals xff09 其中 xff1a number 待做截取处理的数值 decimals 指明需保留小数点后面的位数 可选项 x
  • Codeforces Round #589 div.2 C,D

    感觉这一场的复杂度非常的玄学 也可能是我偷懒太长时间变菜了QAQ C 题意 给出 x n 求x质因子的从1到n的g i p 的连乘思路 求出x的每个质因子 直接连乘到n计算即可 code include lt bits stdc 43 43
  • 五种进程调度算法C++代码实现(FCFS、SJF、Priority、SRTF,Round Robin)

    说明 xff1a 1 假设有只两种状态 xff0c 就绪状态和结束状态 进程的初始状态都为就绪状态 2 每次运行所设计的处理器调度程序调度进程之前 xff0c 为每个进程随机生成它的要求运行时间 3 模拟处理器调度 xff0c 被选中的进程
  • Codeforces Round #852(A~D)

    比赛原地址 xff1a Dashboard Codeforces Round 852 Div 2 Codeforces A Yet Another Promotion 买a种商品会买m送1 xff0c b种则不会 那么当a种商品单价小于等于
  • Codeforces Beta Round #2

    codeforces 2A Winner codeforces 2B The least round way codeforces 2C Commentator problem 这期题目想对感觉较难 A敲了十多分钟 B是想了很久才开始写的中
  • Codeforces Round #774 (Div. 2)(A-C)

    Problem A Codeforces 签到题 xff0c 判断s里面最多能够有多少个 AC代码 pragma GCC optimize 2 pragma GCC optimize 3 pragma GCC optimize 34 Ofa
  • Codeforces Round #201 (Div. 2) E - Number Transformation II

    题意 xff1a 给你一个数组xi和两个数a和b xff0c 求通过两个途径由a到b的最小次数 xff0c 1 当前的a减去1 xff0c 2 当前的a减去a xi 思路 xff1a 首先考虑xi有重复元素 xff0c 所以去重 xff0c
  • Codeforces Round #706 (Div. 2)

    代码 xff1a span class token macro property span class token directive keyword include span span class token string lt iost
  • Codeforces Round #368 (Div. 2) A C

    大清早发现自己的rating涨了72分还是很高兴的 xff0c 毕竟之前都是在掉分 xff0c 还差9分才能到宝蓝啊 xff0c 果然还是小菜鸡 A Brain 39 s Photos 大水题 xff0c 要不是这个codeforces是外
  • Codeforces Round #210 (Div. 2)

    本不想写 xff0c 毕竟就打了一个小时 xff08 训练题变成个人赛了T T xff09 xff0c 但是第一次水题4分钟搞定 xff0c 手速一点没涨 xff0c 纯粹就是脑子快 A Levko and Table 题意 xff1a 输
  • Codeforces Raif Round 1 (Div. 1 + Div. 2) D

    D Bouncing Boomerangs 分析 一个stack用于存只有一个的物品的行的物品位置 xff0c 一个queue用于存有两个物品的行的左边物品位置 xff08 其实这两个容器用stack还是queue无所谓 xff0c 只是这
  • C. Good String Codeforces Round #560 (Div. 3)

    C Good String time limit per test 1 second memory limit per test 256 megabytes input standard input output standard outp
  • STL priority_queue使用

    转自 xff1a http www cnblogs com lvpengms archive 2010 04 05 1704669 html 包含priority queue 的头文件是 lt queue gt priority queue
  • C++ 队列(queue、priority_queue)使用简述

    目录 1 queue有关函数的作用 2 priority queue 有关函数作用 3 queue 测试用例 4 priority queue 测试用例 至于队列的结构与原理 xff08 FIFO xff0c 先入先出 xff09 这里就不
  • c++中的floor, ceil, round

    xfeff xfeff 2 1 2 6 2 1 2 6 floor 不大于自变量的最大整数 2 2 3 3 ceil 不小于自变量的最小整数 3 3 2 2 round 四舍五入到最邻近的整数 2 3 2
  • Codeforces Round #677 (Div. 3) 题解

    Codeforces Round 677 Div 3 题解 A Boring Apartments 题目 题解 简单签到题 xff0c 直接数 xff0c 小于这个数的 43 10 43 10 43 1 0 代码 span class to
  • Codeforces Round #588 (Div. 1)

    Contest Page 因为一些特殊的原因所以更得不是很及时 A sol 不难发现当某个人diss其他所有人的时候就一定要被删掉 维护一下每个人会diss多少个人 xff0c 当diss的人数等于剩余人数 1 的时候放队列里 xff0c
  • python中round函数的一个小坑——奇进偶弃

    gt gt gt round 10 5 按照round的四舍五入 本来应该是11的 但是这里是10 10 gt gt gt round 11 5 整数部分为奇数的时候 又进位了 这里很迷 值得关注一下 12 总结一下 其实就是取靠近的偶数
  • 磁盘调度算法(FCFS、SSTF)例题

    一 原理 先来先服务 FCFS first come first service 根据进程请求访问磁盘的先后次序进行调度 最短寻道时间优先 SSTF Shortest Seek Time First 选择访问的磁道与当前磁头所在的磁道距离最
  • 图解五种磁盘调度算法, FCFS, SSTF, SCAN, C-SCAN, LOOK

    一 FCFS 调度 先来先服务 磁盘调度的最简单形式当然是先来先服务 FCFS 算法 虽然这种算法比较公平 但是它通常并不提供最快的服务 例如 考虑一个磁盘队列 其 I O 请求块的柱面的顺序如下 98 183 37 122 14 124

随机推荐

  • android日志抓取

    目录说明 00 mtk dump mtk dump文件 01 qcom dump qcom dump文件
  • 带你走进EJB--EJB和Spring对比

    通过对 EJB 系列的总结和学习我们已经对 EJB 有了基本的了解 但是为了更进一步的去深入学习 EJB 我们很有必要将它拿出来跟之前非常熟悉的 Spring 进行一下对比 通过对比来了解这两个内容的相同与不同之处 更有利于我们对两者进行深
  • Dubbo之旅--Provider示例

    在本篇文章中我们将通过集体的示例来对 Dubbo 的提供和消费进行代码层面的认识 这里所介绍的是基本的提供者和消费者通过 Spring 容器来进行相关的提供和消费的服务 首先看整个示例的项目结构如下 我们通过 Maven 的方式来进行示例
  • Dubbo之旅--问题汇总

    在工作和学习的过程中 具体运用 Dubbo 的时候遇到了很多的问题 这些问题一方面让自己进一步了解所谓的 dubbo 另一方面通过对它们的总结和分析能够在工作中加倍的提高效率 接下来将会对遇到的和别人总结的一些常见的问题进行汇总 1 增加提
  • Dubbo之旅--集群容错和负载均衡

    当我们的系统中用到 Dubbo 的集群环境 因为各种原因在集群调用失败时 xff0c Dubbo提供了多种容错方案 xff0c 缺省为failover重试 Dubbo 的集群容错在这里想说说他是因为我们实际的项目中出现了此类的问题 因为依赖
  • 我和敏捷开发的故事--敏捷角色-SM

    通过上篇文章我们已经知道了敏捷角色中 PO 的角色内容 接下来的一个敏捷角色在敏捷开发中非常关键 但是往往很多项目实践中都没有很好的把控好这个角色 让他或多或少的没有起到相应的作用 这个角色就是 ScrumMaster Scrum Mast
  • backup

    backup
  • backup

    backup
  • backup

    xfeff xfeff backup
  • 工程硕士考试复习小结

    工程硕士考试复习到现在已经接近尾声 后天就要奔赴省城石家庄赶考了 整个工程硕士的复习过程从十月初开始到现在将近一个月的时间 对所需要进行考试的科目进行整体复习 复习的形式前阶段主要是视频讲解中间阶段是看相应的文档和知识点 最后就是进行专项练
  • 手机浏览器唤起微信实现分享

    html部分 xff1a lt script src 61 34 mshare js 34 gt lt script gt 引进mshare js
  • 中国的教育我们每个人都有责任

    这篇文章将我带入了深深的思考之中 给将要进入大学的你们 xff1a 一个已毕业两年的学长的人生感慨 xff01 面对中国的教育现状 很多的学生 老师 甚至校长 采取的态度是接受 所做的行动是适应和顺从 非常钦佩作者有着自己独立的思想 思想者
  • Eclipse下启动tomcat报错:/bin/bootstrap.jar which is referenced by the classpath, does not exist.

    1 错误 xff1a 在 Eclipse 下启动 tomcat 的时候 xff0c 报错为 xff1a Eclipse 下启动 tomcat 报错 xff1a The archive C Program Files x86 Java jdk
  • centos + electron

    在contos上运行electron 首先配置好ssh 43 x11 可以界面显示 配置ssh 43 x11 然后运行 electron quick start 问题 xff1a 运行electorn 报错 error while load
  • Ubuntu终端运行 .sh 文件出现Syntax error: “(” unexpected”解决办法

    在安装Anaconda的sh程序时 xff0c span class token function sh span Anaconda3 2021 11 Linux x86 64 sh 出现Syntax error 34 34 unexpec
  • 女程序员过三奔四,你的名字是迷茫???/孩子是我幸福的源泉

    Leo 博客 周一 周五固定更新 我的邮箱 xff1a Careerdesign 64 foxmail com 上次讲的是我的博客点击过百万 xff0c 写了 假如生活欺骗了你 今天说说 xff0c 过三奔四的女程序员的职业规划 Leo 您
  • AndroidStudio的插件(Plugin)无法卸载(Uninstall)、安装(Install)、更新(Update)

    2016年6月22日 星期三 自定义android studio的配置文件目录后 xff0c 无法正常安装和卸载插件 xff0c 是何原因 xff1f 知乎 https www zhihu com question 38604486 不知道
  • 软件项目产品化之路

    软件项目产品化之路 2 产品化之路 2 1 困惑 软件项目产品化是大量软件企业 xff0c 特别是应用型软件研发企业所必须面临的问题 不论是小型的软件公司和中大型的软件企业 xff0c 在面对软件项目和软件产品 xff0c 都有诸多困惑 到
  • 软件产品化的一些见解

    软件产品化的定义 软件产品化 即客户无需为软件添加或调整代码和语句即能完成软件的安装配置 应用初始化 系统管理 用户使用的全过程 并且软件至少能满足80 以上的用户某一组应用需求 软件产品化只是完成了产品的生产环节 后面的产品销售 市场推广
  • 五种进程调度算法C++代码实现(FCFS、SJF、Priority、SRTF,Round Robin)

    说明 xff1a 1 假设有只两种状态 xff0c 就绪状态和结束状态 进程的初始状态都为就绪状态 2 每次运行所设计的处理器调度程序调度进程之前 xff0c 为每个进程随机生成它的要求运行时间 3 模拟处理器调度 xff0c 被选中的进程