操作系统实验 多级反馈队列,时间片轮转,动态优先数

可能有错误或伪算法。

#include <iostream>
#include <string>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <windows.h>
#include <ctime>
#include <random>

#define out(x) cout << #x << ":\t" << x << endl
#define out2(x) cout << #x << ":\t"
#define nullptr 0

using namespace std;

constexpr int inf = 0x3f3f3f3f;

/*输出指针控制*/
void gotoxy(int _x, int _y){
    COORD pos = {_x, _y};
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(hOut, pos);
}

/*PCB模块定义*/
class PCB{

public:

    string name;
    char statement = 'w';
    int priorityLevel;
    int arrivalTime;
    int needTime;
    int usedTime = 0;
    int finTime = 0;
    int counter = 0;
    PCB *next = nullptr;

    void print(){
    	printf("-----------------\n");
        out(name);
        out(statement);
        out(priorityLevel);
        out(arrivalTime);
        out(needTime);
        out(usedTime);
        out(finTime);
        puts("");
    }

    void print2(){
    	printf("-----------------\n");
        out(name);
        out(statement);
        out(counter);
        out(arrivalTime);
        out(needTime);
        out(usedTime);
        out(finTime);
        puts("");
    }

    void print3(){
		printf("-----------------\n");
        out(name);
        out(statement);
        out(arrivalTime);
        out(needTime);
        out(finTime);
		return ;
	}
};

/*动态优先数*/
class prioRunner{

public:
	/*进程数量*/
	int N;

	/*完成队列,就绪队列,运行队列,未到达队列*/
	PCB *finhead = nullptr, *readyhead = nullptr,
 		*running = nullptr, *notarrival = nullptr;

	/*插入未到达队列*/
	void insertarrival(PCB *p){
		PCB *now, *nowf;
	    nowf = nullptr;
	    now = notarrival;
		while (now != nullptr){
			if (now->arrivalTime < p->arrivalTime){
	        	nowf = now;
	        	now = now->next;
			}else break;
		}

		if (nowf == nullptr){
	    	p->next = notarrival;
	    	notarrival = p;
		}else{
			p->next = nowf->next;
			nowf->next = p;
		}

		return ;
	}

	/*插入就绪队列*/
	void insertready(PCB *p){
	    PCB *now, *nowf;
	    nowf = nullptr;
	    now = readyhead;

	    while (now != nullptr){
	        if (now->priorityLevel >= p->priorityLevel){
	        	nowf = now;
	        	now = now->next;
			}else break;
	    }

	    if (nowf == nullptr){
	    	p->next = readyhead;
	    	readyhead = p;
		}else{
			p->next = nowf->next;
			nowf->next = p;
		}

	    return ;
	}

	/*PCB队列信息输出*/
	void information(){
	    PCB *p;
	    cout << "---------\nnotarrival:\n";
	    p = notarrival;
	    while (p != nullptr){
	    	p->print();
	    	p = p->next;
		}

		cout << "---------\nreadyhead:\n";
	    p = readyhead;
	    while(p != nullptr){
	        p->print();
	        p = p->next;
	    }

	    cout << "---------\nrunning:\n";
	    p = running;
	    while(p != nullptr){
	        p->print();
	        p = p->next;
	    }

	    cout << "---------\nfinhead:\n";
	    p = finhead;
	    while (p != nullptr){
	        p->print();
	        p = p->next;

	    }
	    return ;
	}

    /*PCB清空*/
	void clear(){
	    PCB *p,*nxt;

	    p = notarrival;
	    while (p != nullptr){
	    	nxt = p->next;
	    	delete p;
	    	p = nxt;
		}

	    p = readyhead;
	    while(p != nullptr){
	    	nxt = p->next;
	    	delete p;
	    	p = nxt;
	    }

	    p = running;
	    while(p != nullptr){
	    	nxt = p->next;
	    	delete p;
	    	p = nxt;
	    }

	    p = finhead;
	    while (p != nullptr){
	    	nxt = p->next;
	    	delete p;
	    	p = nxt;
	    }
	    finhead = nullptr, readyhead = nullptr,
		running = nullptr, notarrival = nullptr;

	    return ;
	}

	/*建表*/
	void makelist(){
	    PCB *p;
	    int time;
	    finhead = nullptr, readyhead = nullptr,
		running = nullptr, notarrival = nullptr;

	    for (int i = 1; i <= N; i++){
	        p = new PCB;
			cout << "input name:";
			cin >> p->name ;
			cout << "input needTime:";
			cin >> p->needTime ;
			cout << "input arrivalTime:";
			cin >> p->arrivalTime;
	        p->priorityLevel = 40 - p->needTime;

	        if (p->arrivalTime == 0){
	            if (readyhead != nullptr){
	                insertready(p);
	            }
	            else{
	                readyhead = p;
	            }
	        }else{
	        	if (notarrival != nullptr){
	                insertarrival(p);
	            }
	            else{
	                notarrival = p;
	            }
			}
			p->print();
	    }

		if (readyhead != nullptr){
		    running = readyhead;
		    readyhead = readyhead->next;
		    running->statement = 'r';
		    running->next = nullptr;
		}

	    return ;
	}

	/*运行程序*/
	void run(){
		PCB *p;
		int runtime = 0;
		while (running != nullptr || notarrival != nullptr){
            runtime++;
            if(running != nullptr){
                running->usedTime++;
                running->priorityLevel -= 2;
                if (running->usedTime == running->needTime){
                    running->next = finhead;
                    running->statement = 'f';
                    running->finTime = runtime;
                    finhead = running;
                    running = nullptr;
                }
            }
            PCB *p = readyhead;
            while (p != nullptr){
                p->priorityLevel++;
                p = p->next;
            }

            p = notarrival;
            while (p != nullptr){
                if (p->arrivalTime <= runtime){
                    notarrival = p->next;
                    if (readyhead != nullptr)
                        insertready(p);
                    else{
                        p->next = nullptr;
                        readyhead = p;
                    }
                    p = notarrival;
                }
                else
                    p = p->next;
            }

			if(running == nullptr){
                if(readyhead != nullptr){
                    running = readyhead;
                    running->statement = 'r';
                    readyhead = readyhead->next;
                    running->next = nullptr;
                }
            }

            if(readyhead != nullptr && running != nullptr){
                if(readyhead->priorityLevel > running->priorityLevel){
                    running->statement = 'w';
                    insertready(running);
                    running = readyhead;
                    running->statement = 'r';
                    readyhead = readyhead->next;
                    running->next = nullptr;
                }
            }
            Sleep(500);
            system("cls");
            //gotoxy(0,0);
            cout << endl << "##RUNTIME: " << runtime << endl;information();

		}
		return ;
	}
};

/*时间轮转*/
class loopRunner{

public:
	/*进程数量,片大小*/
	int N, L;

	/*完成队列,就绪队列,运行队列,未到达队列*/
	PCB *finhead = nullptr, *readyhead = nullptr,
 		*running = nullptr, *notarrival = nullptr;

    /*就绪队尾*/
    PCB *readytail = nullptr;

    /*插入未到达队列*/
	void insertarrival(PCB *p){
		PCB *now, *nowf;
	    nowf = nullptr;
	    now = notarrival;
		while (now != nullptr){
			if (now->arrivalTime < p->arrivalTime){
	        	nowf = now;
	        	now = now->next;
			}else break;
		}

		if (nowf == nullptr){
	    	p->next = notarrival;
	    	notarrival = p;
		}else{
			p->next = nowf->next;
			nowf->next = p;
		}

		return ;
	}

	/*插入就绪队列*/
	void insertready(PCB *p){
	    p->next = nullptr;
        readytail->next = p;
		readytail = readytail->next;
	    return ;
	}

	/*PCB队列信息输出*/
	void information(){
	    PCB *p;
	    cout << "---------\nnotarrival:\n";
	    p = notarrival;
	    while (p != nullptr){
	    	p->print2();
	    	p = p->next;
		}

		cout << "---------\nreadyhead:\n";
	    p = readyhead;
	    while(p != nullptr){
	        p->print2();
	        p = p->next;
	    }

	    cout << "---------\nrunning:\n";
	    p = running;
	    while(p != nullptr){
	        p->print2();
	        p = p->next;
	    }

	    cout << "---------\nfinhead:\n";
	    p = finhead;
	    while (p != nullptr){
	        p->print2();
	        p = p->next;

	    }
	    return ;
	}

    /*PCB清空*/
	void clear(){
	    PCB *p,*nxt;

	    p = notarrival;
	    while (p != nullptr){
	    	nxt = p->next;
	    	delete p;
	    	p = nxt;
		}

	    p = readyhead;
	    while(p != nullptr){
	    	nxt = p->next;
	    	delete p;
	    	p = nxt;
	    }

	    p = running;
	    while(p != nullptr){
	    	nxt = p->next;
	    	delete p;
	    	p = nxt;
	    }

	    p = finhead;
	    while (p != nullptr){
	    	nxt = p->next;
	    	delete p;
	    	p = nxt;
	    }
        finhead = nullptr, readyhead = nullptr,
		running = nullptr, notarrival = nullptr;

	    return ;
	}

	/*建表*/
	void makelist(int tl=5){
	    PCB *p;
	    int time;
	    finhead = nullptr, readyhead = nullptr,
		running = nullptr, notarrival = nullptr;

        L = tl; //时间片大小

	    for (int i = 1; i <= N; i++){
	        p = new PCB;
			cout << "input name:";
			cin >> p->name ;
			cout << "input needTime:";
			cin >> p->needTime ;
			cout << "input arrivalTime:";
			cin >> p->arrivalTime;

	        if (p->arrivalTime == 0){
	            if (readyhead != nullptr){
	                insertready(p);
	            }
	            else{
	                readyhead = p;
	                readytail = p;
	            }
	        }else{
	        	if (notarrival != nullptr){
	                insertarrival(p);
	            }
	            else{
	                notarrival = p;
	            }
			}
			p->print();
	    }

		if (readyhead != nullptr){
		    running = readyhead;
		    running->counter = L;
		    readyhead = readyhead->next;
		    running->statement = 'r';
		    running->next = nullptr;
		}


	    return ;
	}

    void run(){
        int runtime = 0;
        while (running != nullptr || notarrival != nullptr){
            runtime++;
            //puts("q");
            if (running != nullptr){
                running->usedTime++;
                running->counter--;
                if (running->usedTime == running->needTime){
                    running->next = finhead;
                    running->statement = 'f';
                    running->finTime = runtime;
                    finhead = running;
                    running = nullptr;
                }
                else if (running->counter <= 0){
                    running->next = nullptr;
                    running->statement = 'w';
                    insertready(running);
                    running = nullptr;
                }
            }

            if (running == nullptr){
                if(readyhead != nullptr){
                    running = readyhead;
                    running->statement = 'r';
                    running->counter = L;
                    readyhead = readyhead->next;
                    running->next =nullptr;
                }
            }

            PCB *p = notarrival;
            while (p != nullptr){
                if (p->arrivalTime <= runtime){
                    notarrival = p->next;
                    if (readyhead != nullptr)
                        insertready(p);
                    else{
                        p->next = nullptr;
                        readyhead = p;
                        readytail = p;
                    }
                    p = notarrival;
                }
                else
                    break;
            }
            Sleep(500);
            system("cls");
            //gotoxy(0,0);
            cout << endl << "##RUNTIME: " << runtime << endl;information();

        }
        return ;
    }

};

/*多重队列数量*/
constexpr int maxn = 3;
/*多级反馈队列*/
class multiqueueRunner{

public:

	int N, L[maxn];

	PCB *finhead = nullptr,
 		*running = nullptr, *notarrival = nullptr;

    /*多重队列*/
    PCB **multiquehead = new PCB *[maxn];
    PCB **multiquetail = new PCB *[maxn];

    /*初始化*/
    multiqueueRunner(){
        L[0] = 1 << 1;
        for (int i=1; i<maxn; i++){
            L[i] = L[i-1] << 1;
        }

        for (int i = 0; i < maxn; i++){
            multiquehead[i] = nullptr;
            multiquetail[i] = nullptr;
		}
    }

    /*插入未到达队列*/
	void insertarrival(PCB *p){
		PCB *now, *nowf;
	    nowf = nullptr;
	    now = notarrival;
		while (now != nullptr){
			if (now->arrivalTime < p->arrivalTime){
	        	nowf = now;
	        	now = now->next;
			}else break;
		}

		if (nowf == nullptr){
	    	p->next = notarrival;
	    	notarrival = p;
		}else{
			p->next = nowf->next;
			nowf->next = p;
		}

		return ;
	}

	/*插入就绪队列*/
	void insertready(int x, PCB *p){
        p->next = nullptr;

	    if(multiquehead[x] == nullptr){
            multiquehead[x] = p;
            multiquetail[x] = p;
	    }else{
            multiquetail[x]->next = p;
            multiquetail[x] = multiquetail[x]->next;
	    }
	    return ;
	}

	/*PCB队列信息输出*/
	void information(){
	    PCB *p;
	    cout << "---------\nnotarrival:\n";
	    p = notarrival;
	    while (p != nullptr){
	    	p->print2();
	    	p = p->next;
		}

		/*就绪队列表*/
        cout << "---------\nmultique:\n";
		for (int i = 0; i < maxn; i++){
            p = multiquehead[i];
            cout << "que #" << i << ": " << endl;
            while (p != nullptr){
                p->print2();
                p = p->next;
            }
		}

	    cout << "---------\nrunning:\n";
	    p = running;
	    while(p != nullptr){
	        p->print2();
	        p = p->next;
	    }

	    cout << "---------\nfinhead:\n";
	    p = finhead;
	    while (p != nullptr){
	        p->print2();
	        p = p->next;

	    }
	    return ;
	}

    /*PCB清空*/
	void clear(){
	    PCB *p,*nxt;

	    p = notarrival;
	    while (p != nullptr){
	    	nxt = p->next;
	    	delete p;
	    	p = nxt;
		}

		for (int i = 0; i < maxn; i++){
            p = multiquehead[i];
            while (p != nullptr){
                nxt = p->next;
                delete p;
                p = nxt;
            }
		}

	    p = running;
	    while(p != nullptr){
	    	nxt = p->next;
	    	delete p;
	    	p = nxt;
	    }

	    p = finhead;
	    while (p != nullptr){
	    	nxt = p->next;
	    	delete p;
	    	p = nxt;
	    }
        finhead = nullptr,
		running = nullptr, notarrival = nullptr;

        for (int i = 0; i < maxn; i++){
            multiquehead[i] = nullptr;
            multiquetail[i] = nullptr;
		}

	    return ;
	}

	/*建表*/
	void makelist(){
	    PCB *p;

	    clear();

	    for (int i = 1; i <= N; i++){
	        p = new PCB;
			cout << "input name:";
			cin >> p->name ;
			cout << "input needTime:";
			cin >> p->needTime ;
			cout << "input arrivalTime:";
			cin >> p->arrivalTime;

	        if (p->arrivalTime == 0){
                insertready(0, p);
	        }else{
	        	if (notarrival != nullptr){
	                insertarrival(p);
	            }
	            else{
	                notarrival = p;
	            }
			}
			p->print2();
	    }

		if (multiquehead[0] != nullptr){
		    running = multiquehead[0];
		    running->counter = L[0];
		    multiquehead[0] = multiquehead[0]->next;
		    running->statement = 'r';
		    running->next = nullptr;
		}


	    return ;
	}

	/*运转周期*/
	void after_run(){

	    cout << endl << "after_run:" << endl;

		PCB *p = finhead;
		int cnt = 0;
		float wsum = 0.0;
		int ssum = 0;

		while (p != nullptr){
			int stayTime = p->finTime - p->arrivalTime;
			float weigthTime = (float)stayTime / p->needTime;
			p->print3();
			out(stayTime);
			out2(weigthTime);printf("%.2f\n",weigthTime);

			ssum += stayTime;
			wsum += weigthTime;
			cnt++;
			puts("");
			p = p->next;
		}

		float averageStayTime = (float)ssum / cnt;
		float averageWeigthTime = wsum / cnt;

		out2(averageStayTime);printf("%.2f\n",averageStayTime);
		out2(averageWeigthTime);printf("%.2f\n",averageWeigthTime);

		return ;
	}

	/*算法主体*/
    void run(){
        int runtime = 0;
        int nowque = 0;
        while (running != nullptr || notarrival != nullptr){
            runtime++;
            if (running != nullptr){
                running->usedTime++;
                running->counter--;
                if (running->usedTime == running->needTime){
                    running->next = finhead;
                    running->statement = 'f';
                    running->finTime = runtime;
                    finhead = running;
                    running = nullptr;
                }
                else if (running->counter <= 0){
                    running->next = nullptr;
                    running->statement = 'w';
                    /*下面取最小值保证在边界时执行RR算法*/
                    running->counter = L[min(nowque + 1, maxn - 1)];
                    insertready(min(nowque + 1, maxn - 1), running);
                    running = nullptr;
                }
            }

            PCB *p = notarrival;
            while (p != nullptr){
                if (p->arrivalTime <= runtime){
                    notarrival = p->next;
                    if(nowque > 0){
                        /*正在运行低优先级任务则抢占*/
                        if(running != nullptr)
                            insertready(nowque, running);
                        running = p;
                        running->next = nullptr;
                        running->counter = L[0];
                        nowque = 0;
                    }else{
                        insertready(0, p);
                    }
                    p = notarrival;
                }
                else
                    break;
            }

            if (running == nullptr){
                while (multiquehead[nowque] == nullptr && nowque+1 < maxn){
                    nowque++;
                }
                if(multiquehead[nowque] != nullptr){
                    running = multiquehead[nowque];
                    running->statement = 'r';
                    multiquehead[nowque] = multiquehead[nowque]->next;
                    running->next = nullptr;
                }
            }
            //system("cls");
            //gotoxy(0,0);
            //cout << endl << "##RUNTIME: " << runtime << endl;information();
            //Sleep(5000);
        }

        //after_run();

        return ;
    }

};

int main(){
	//freopen("a.txt","r",stdin);

    cout << "please input N:" << endl;

    multiqueueRunner runner;

    cin >> runner.N;

    runner.makelist();

    runner.run();

    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值