C++模拟进程调度---多线程加入信号量控制临界区

分为三级反馈队列
每次只从第一级队列里取出进程。
每执行三次一级队列的进程发生一次队列调整。

三次执行:前两次遵从最短优先调度,最后一次随机取进程,
为的是让调整上来的进程可以有机会执行

调整:从二级队列和三级队列分别随机取两个和一个进程
放入一级队列里面参与竞争。

直到一级队列空则所有的进程执行完毕

加了一个线程专门产生进程

/**
* title :C++模拟进程调度---多线程加入信号量控制临界区
* author : liyunhao
* date:2018.04.24
* time : 21:10
*/
/*
调度的思想,分为三级反馈队列。
每次只从第一级队列里取出进程。

每执行三次一级队列的进程发生一次队列调整。

三次执行:前两次遵从最短优先调度,最后一次随机取进程,
为的是让调整上来的进程可以有机会执行

调整:从二级队列和三级队列分别随机取两个和一个进程
放入一级队列里面参与竞争。

直到一级队列空则所有的进程执行完毕

加了一个线程专门产生进程
*/

#include<iostream>
#include<list>
#include <time.h>
#include <stdlib.h>
#include <windows.h>
using namespace std;
int mutex = 0;
class tool{//工具类
public:
    int timeInterval;
    tool(){
        srand((unsigned)time( NULL ));//设置随机数
        timeInterval = 10;//进程执行的单位间隔
    }

    int getRandom(int a,int b){//返回指定范围的随机数
        int range = b - a;
        if(range==0){
            return 0;
        }else{
            return a + rand()%range;
        }

    }

};

class process{//进程类
public:
    int pid;    //进程编号
    int length;
    int level;
    process(int pid,int lengthOfProcess ){
        length = lengthOfProcess;
        if(length <= 0){
            cout<<"进程创建失败!"<<endl;
        }else if(length <= 10){
            level = 1;
            this->pid = pid;
            cout<<"进程"<<pid<<"创建,长度"<<length <<endl;
        }else if(length <= 20){
            level = 2;
            this->pid = pid;
            cout<<"进程"<<pid<<"创建,长度"<<length <<endl;
        }else{
            level = 3;
            this->pid = pid;
            cout<<"进程"<<pid<<"创建,长度"<<length <<endl;
        }
    }
    bool ajustLevel(){//调整进程的优先级
        if(length <= 0){
            cout<<"进程运行完毕!"<<endl;
            return false;
        }else if(length <= 10){
            level = 1;
            return true;
        }else if(length <= 20){
            level = 2;
            return true;
        }else{
            level = 3;
            return true;
        }
    }
    bool doTheProcess(int timeLength){
        if(length <=0 ){
            cout<<"进程已经运行完毕!"<<endl;
            return false;
        }else{
            length -= timeLength;
            ajustLevel();
            if(length < 0){
                length = 0;
                return true;
            }else{
                return true;
            }
        }

    }
    bool finishThePro(){
        cout<<"进程"<<pid<<"执行完毕"<<endl;
    }

};

class processQueue{
public:
    int level;  //队列的优先级
    list<process* > List[3];//三个不同优先级的队列
    processQueue(){
        ;
    }

    bool processIncoming(process*pro){
        int level = pro->level;
        int pid = pro->pid;
        if(level ==1){
            List[0].push_back(pro);
            cout<<"进程"<<pid<<"加入队列"<<level<<endl;
            return true;
        }else if(level ==2){
            List[1].push_back(pro);
            cout<<"进程"<<pid<<"加入队列"<<level<<endl;
            return true;
        }else if(level ==3){
            List[2].push_back(pro);
            cout<<"进程"<<pid<<"加入队列"<<level<<endl;
            return true;
        }else{
            cout<<"未知的优先级!"<<endl;
            return false;
        }
    }

    //从指定队列里面找一个进程,并从原来的队列删除该进程
    process* findProFromList(int listNum){
        listNum--;
        list<process*>::iterator itor;
        list<process*>::iterator delNode;
        int currentMin = 9999;
        process* shortestPro;
        if(List[listNum].size() == 0){
            //cout<<"队列"<<listNum+1<<"的进程已经执行完毕,获取失败"<<endl;
            return NULL;
        }else{
            //cout<<"元素个数"<<List1.size()<<endl;// 返回list中的元素个数
            for(itor = List[listNum].begin();itor!=List[listNum].end();itor ++){
                if((*itor)->length < currentMin){
                    currentMin = (*itor)->length;
                    shortestPro = (*itor);
                    delNode = itor;
                }
            }
            List[listNum].erase(delNode);//从进程队列中删除该进程
            return shortestPro;
        }

    }


    process* findProFromListByRandom(int listNum){
        listNum--;
        list<process*>::iterator itor;
        int currentMin = 9999;
        process* shortestPro;
        tool atool;

        if(List[listNum].size() == 0){
            //cout<<"队列"<<listNum+1<<"的进程已经执行完毕,获取失败"<<endl;
            return NULL;
        }else{
            itor = List[listNum].begin();
            int queLen = List[listNum].size();
            //cout<<"queLen :"<<queLen<<endl;
            int randomNum = atool.getRandom(0,queLen-1);
            //cout<<"randomNum :"<<randomNum<<endl;
            //cout<<"随机选取进程"<<randomNum<<endl;
            advance(itor,randomNum);
            shortestPro = (*itor);
            List[listNum].erase(itor);//从进程队列中删除该进程
            //printQue(1);
            return shortestPro;
        }


    }
    process* selectFromList1AndDoIt(){

        process* shortestPro;
        shortestPro = findProFromList(1);
        if(shortestPro!= NULL){
            shortestPro->finishThePro();
            //ajustLevelQueues();
            return shortestPro;
        }else{
            return NULL;
        }

    }
    process* selectList1ByRondomAndDoIt(){

        process* RondomPro;
        RondomPro = findProFromListByRandom(1);
        if(RondomPro!= NULL){
            RondomPro->finishThePro();
            //ajustLevelQueues();
            return RondomPro;
        }else{
            return NULL;
        }

    }
    bool ajustLevelQueues(){
        cout<<"调整"<<endl;
        Sleep(500);
        process* p[3];
        p[0] = findProFromListByRandom(2);//从第二级队列随机获取进程
        p[1] = findProFromListByRandom(2);//从第二级队列随机获取进程
        p[2] = findProFromListByRandom(3);//从第三级队列随机获取进程
        //process* p3 = findProFromList(3);//从第三极队列中获取最短时间进程
        if( (p[0]==NULL) &&(p[1]==NULL) && (p[2]== NULL)){

            //cout<<"2,3队列已经空了,调整失败"<<endl;
            return false;
        }else if((p[0]==NULL)  && (p[2]!= NULL)){
            p[0] = findProFromListByRandom(3);//从第二级队列获取最短时间进程
            p[1] = findProFromListByRandom(3);//从第三级队列获取最短时间进程
        }else if((p[0]!=NULL) &&(p[1]==NULL) && (p[2]!= NULL)){
            p[1] = findProFromListByRandom(3);//从第二级队列获取最短时间进程
        }else if((p[0]!=NULL) &&(p[1]!=NULL) && (p[2]== NULL)){
            p[2] = findProFromListByRandom(2);//从第二级队列获取最短时间进程
        }


        if(p[0]){
            p[0]->level = 1;
            cout<<"调整"<<p[0]->pid<<endl;
            List[0].push_back(p[0]);//放入第一级队列
        }
        if(p[1]){
            p[1]->level = 1;
            cout<<"调整"<<p[1]->pid<<endl;
            List[0].push_back(p[1]);//放入第一级队列
        }
        if(p[2]){
            p[2]->level = 1;
            cout<<"调整"<<p[2]->pid<<endl;
            List[0].push_back(p[2]);//放入第一级队列
        }
        return true;
    }
    void printQue(int listNum){
        listNum--;
        list<process*>::iterator itor;
        for(itor = List[listNum].begin();itor!=List[listNum].end();itor ++){

                cout<<(*itor)->pid<<" ";
        }
        cout<<endl;
    }

};
class GanttChart{//输出甘特图的类
public:
    string GamtString;
    int proNum;
    GanttChart(){
        GamtString += "|";
        proNum = 0;

    }
    bool add(process *p){
        //for(int i=0 ;i<p->length;i++){
            char temp[10];
            itoa(p->pid,temp,10);
            GamtString += temp;
        //}
        GamtString += "|";
        proNum ++;
        if(proNum!=0 && proNum % 25 ==0){
            GamtString ="";//每隔25个清空一次甘特图
        }
    }
    void print(){
        cout<<"                 该进程调度的甘特图:"<<endl;
        cout<<"____________________________________________________________________"<<endl;
        cout<<GamtString<<endl;
        cout<<" ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄"<<endl;
    }

};
//主函数与线程的共享变量
int currPro;
tool tool1;
processQueue proqueue;
process *pro ;
process *proPrint;
GanttChart gant;
int timeInterval;

class index{
public:


    index(){
        currPro = 0;

        timeInterval = tool1.timeInterval;
    }

    void IndexGo(){
        int proCountForPrint = 0;
        while(1){
            while(mutex==1);
            mutex=1;//加锁保护临界区
            cout<<"在主函数里面"<<endl;
            for(int i=0;i<3;i++){
                if(proqueue.List[0].size()>0){
                    proPrint=proqueue.selectFromList1AndDoIt();
                    Sleep(proPrint->length * timeInterval);
                    gant.add(proPrint);
                    proCountForPrint++;
                }
            }

            proqueue.ajustLevelQueues();
            if(proCountForPrint!=0 && proCountForPrint % 24==0){
               gant.print();
            }

            mutex=0;//解锁
            Sleep(1000);//便于观察
        }


    }
};


DWORD WINAPI ThreadProc(LPVOID lpParameter)
{


    while(1){
        while(mutex==1);
        mutex = 1;          //加锁保护临界区
        cout<<"在线程里面"<<endl;
        int RandomPronum = tool1.getRandom(1,5);
        for(int i = 0;i < RandomPronum;i++){//随机生成不同(1-5个)的进程
            int Len = tool1.getRandom(1,50);
            pro = new process(currPro,Len);
            proqueue.processIncoming(pro);
            currPro++;
        }

        mutex = 0;//解锁
        Sleep(1000);//便于观察

    }

    return 0;
}
int main(){
    cout<<"模拟进程调度---基于多级队列"<<endl;
    index inde;
    HANDLE hThread1 = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
    inde.IndexGo();


    return 0;
}






猜你喜欢

转载自blog.csdn.net/l1558198727/article/details/80070822