1, Experiment contents and requirements
- Priority law, rotation law
Simplified assumptions
1) The process is computational (no I/O)
2) Process status: ready, running, finish
3) The CPU time required by the process is determined in time slices - Algorithm description
1) Priority law - dynamic priority
When the current running process runs out of time slices, its priority is subtracted by a constant.
2) Rotation method - requirement
1) The value range of various random numbers generated shall be limited. For example, the CPU time required shall be limited to 1 ~ 20.
2) The number of processes n should not be too large, usually 4 ~ 8
3) Using dynamic data structures
4) Independent programming
2, Experimental flow chart
3, Experimental analysis
Priority scheduling algorithm
Firstly, the time slice rotation method needs to sort the processes according to the priority in real time, and the processes with high priority run first, so the data structure of priority queue is the most appropriate.
PCB also needs to store the name of the process, the required time of the process, the priority of the process and the status of the process. Structure can be adopted, and the sorting mode of the process can be customized at the same time.
During initialization, the required time range of the process is specified as 1-20; Because each time slice ends, the time required for the process is - 1 and the priority is - 3. In order to make the priority not less than 0, the priority is specified as 60-80; The initial state of the process is ready.
When the priority scheduling algorithm is adopted, the state of the process at the head of the team is set to running each time, and then the state of each process is output. If the process status of the team leader is finish at this time, it means that all processes have been completed, that is, exit; Otherwise, after the time slice arrives, the time required by the process is - 1 and the priority is - 3, and then continue to judge whether the process has been completed. If it is completed, set the priority of the process to the minimum 0 and join the queue to ensure that the process is always at the end of the queue in the priority queue.
Round Robin
The rotation method should pay attention to understand the concept of rotation time slice, which specifies the maximum number of time slices that the process can run each time.
In the rotation method, if the occupied time slice is less than the rotation time slice, the process always runs in the CPU occupied by the head of the queue. The ordinary queue is adopted. After the head of the queue is out of line each time, it can only pop in at the end of the queue. Therefore, I adopt the data structure of double ended queue, so that when the occupied time slice is less than the rotation time slice, the process can directly pop into the head of the queue, The time complexity and space complexity are reduced.
In addition, in the rotation method, after the process is completed, it cannot be at the end of the queue like the priority queue, so I opened another queue to store the completed process.
4, Experimental code
#include <bits/stdc++.h> using namespace std; //*************************Priority scheduling algorithm****************************// struct PCB_PSA { int id; //Process name int need_time; //Process time int priority; //Priority of the process string state; //Status of the process //Priority queue sorting: processes with high priority are executed first bool operator<(const PCB_PSA &a) const { return a.priority >= priority; } }; int cnt = 1; //Record time int n; //Number of processes char c; //Selective scheduling algorithm priority_queue<PCB_PSA> pcb_PSA; //Process initialization void init_PSA() { for (int i = 1; i <= n; i++) { PCB_PSA t; t.id = i; t.need_time = rand() % 20 + 1; //The process takes 1 ~ 20 minutes t.priority = rand() % 20 + 60; //The process priority is 60 ~ 80, because every time a time slice is executed, the priority is - 3, and the priority will soon become negative. If this range is adopted, the minimum priority is 0 t.state = "ready"; //The process status is initialized to ready pcb_PSA.push(t); } } //Output current process operation void print_PSA() { priority_queue<PCB_PSA> temp = pcb_PSA; PCB_PSA t; cout << endl << "Current time:" << cnt++ << endl; while (!temp.empty()) { t = temp.top(); temp.pop(); cout << "Process name:" << t.id << "\t Status:" << t.state << "\t Time required:" << t.need_time << "\t Priority:" << t.priority << endl; } } //Priority scheduling void PSA() { PCB_PSA t; while (1) { //Change the status of the team leader process to running, and then output the process execution t = pcb_PSA.top(); pcb_PSA.pop(); if (t.state != "finish")t.state = "running"; pcb_PSA.push(t); print_PSA(); t = pcb_PSA.top(); pcb_PSA.pop(); //If the status of the queue leader process is finish, all processes are completed and exit. if (t.state == "finish")break; //Time slice arrives, process time - 1, priority - 3 t.need_time -= 1; t.priority -= 3; //If the time required for the process is 0, set the priority to the minimum 0; Otherwise, the status changes to ready. if (t.need_time == 0) { t.state = "finish"; t.priority = 0; } else { t.state = "ready"; } pcb_PSA.push(t); } } //********************************************************************// //***************************Time slice rotation scheduling algorithm***************************// struct PCB_RR { int id; //Process name int need_time; //Process time int round_time; //Process rotation time slice int hold_time; //Elapsed time of process string state; //Process status }; //pcb_finish stores the completed process deque<PCB_RR> pcb_RR, pcb_finish; //Process initialization void init_RR() { for (int i = 1; i <= n; i++) { PCB_RR t; t.id = i; t.need_time = rand() % 20 + 1; //The time required for the process ranges from 1 to 20 t.round_time = rand() % 20 + 1; //The process rotation time slice is 1 ~ 20 t.hold_time = 0; //Initialization of process elapsed time to 0 t.state = "ready"; //The process status is initialized to ready pcb_RR.push_back(t); } } //Output current process running status + completed process status void print_RR() { cout << endl << "Current time:" << cnt++ << endl; deque<PCB_RR> temp = pcb_RR; PCB_RR t; while (!temp.empty()) { t = temp.front(); temp.pop_front(); cout << "Process name:" << t.id << "\t Status:" << t.state << "\t Time required:" << t.need_time << "\t Rotation time slice:" << t.round_time << endl; } temp = pcb_finish; while (!temp.empty()) { t = temp.front(); temp.pop_front(); cout << "Process name:" << t.id << "\t Status:" << t.state << "\t Time required:" << t.need_time << "\t Rotation time slice:" << t.round_time << endl; } } //Rotation time slice void RR() { PCB_RR t; while (!pcb_RR.empty()) { //Change the status of the team leader process to running, and then output the current process execution t = pcb_RR.front(); pcb_RR.pop_front(); t.state = "running"; pcb_RR.push_front(t); print_RR(); t = pcb_RR.front(); pcb_RR.pop_front(); //When the time slice arrives, the time required by the process is - 1, and the time occupied by the process is + 1 t.need_time -= 1; t.hold_time += 1; //If the time required for the process is 0, the process execution is completed and enters the pcb_finish queue //If the occupation time = rotation time slice, the occupation time of the process is set to 0, and the team ends //Otherwise, the process will be the first in the team if (t.need_time == 0) { t.state = "finish"; pcb_finish.push_back(t); } else if (t.hold_time == t.round_time) { t.state = "ready"; t.hold_time = 0; pcb_RR.push_back(t); } else { pcb_RR.push_front(t); } } print_RR(); } //*********************************************************************// int main() { srand(time(NULL)); cout << "Please enter the number of processes(4~8 individual): "; cin >> n; cout << "Please select a scheduling method(y: Priority law; n: Rotation method): "; cin >> c; if (c == 'y') { init_PSA(); PSA(); } else if (c == 'n') { init_RR(); RR(); } return 0; }