提问人:SYED ALI MEHDI RIZVI 提问时间:10/11/2023 最后编辑:genpfaultSYED ALI MEHDI RIZVI 更新时间:10/12/2023 访问量:18
输出未出现在多级队列算法中
Output not appearing in Multi-level Queue algorithm
问:
这是一个多级队列调度问题。我已经实现了 4 个级别,其中系统进程队列具有最高优先级,批处理队列具有最低优先级。我使用堆对流程进行排序,以便对系统进程进行优先级调度,对交互式和交互式编辑进程进行循环调度,对批处理进程进行先到先得调度:
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
// Define a struct for representing a process.
class Process {
public:
int pid; // Process ID
int arrivalTime; // Arrival time
string type; // Type of process (System, Interactive, etc.)
int burstTime; // Burst time
int priority; // Priority
int curRunTime; // Current run time
// Default constructor
Process() : pid(0), arrivalTime(0), type(""), burstTime(0), priority(0), curRunTime(0) {
}
// Parameterized constructor
Process(int pid, int arrivalTime, string type, int burstTime, int priority)
: pid(pid), arrivalTime(arrivalTime), type(type), burstTime(burstTime), priority(priority), curRunTime(0) {
}
// Getters and setters for process attributes
int getPid() { return pid; }
int getArrivalTime() { return arrivalTime; }
string getType() { return type; }
int getPriority() { return priority; }
int getBurstTime() { return burstTime; }
void setBurstTime(int burstTime) { this->burstTime = burstTime; }
int getCurRunTime() { return curRunTime; }
void setCurRunTime(int curRunTime) { this->curRunTime = curRunTime; }
};
// Define a class for a priority queue using priority.
class Priority_queue_using_priority {
private:
vector<Process> heap; // The heap data structure
int size; // Current size of the queue
int capacity; // Maximum capacity of the queue
// Helper functions for heap operations
int parent(int i) { return (i - 1) / 2; }
int leftChild(int i) { return 2 * i + 1; }
int rightChild(int i) { return 2 * i + 2; }
void swap(int i, int j) {
Process temp = heap[i];
heap[i] = heap[j];
heap[j] = temp;
}
public:
// Constructor to initialize the priority queue.
Priority_queue_using_priority(int capacity) {
this->capacity = capacity;
this->size = 0;
this->heap = vector<Process>(capacity);
}
// Insert a process into the priority queue based on its priority and arrival time.
void insert(Process process) {
if (size >= capacity) {
cout << "Heap is full, cannot insert." << endl;
return;
}
size++;
int i = size - 1;
heap[i] = process;
while (i != 0) {
if (heap[parent(i)].getPriority() > heap[i].getPriority() ||
(heap[parent(i)].getPriority() == heap[i].getPriority() &&
heap[parent(i)].getArrivalTime() > heap[i].getArrivalTime())) {
swap(i, parent(i));
i = parent(i);
} else {
break;
}
}
}
// Extract the process with the highest priority.
Process extractMin() {
if (size <= 0) {
cout << "Heap is empty." << endl;
return Process(0, 0, "", 0, 0);
}
if (size == 1) {
size--;
return heap[0];
}
Process root = heap[0];
heap[0] = heap[size - 1];
size--;
minHeapify(0);
return root;
}
// Maintain the min-heap property.
void minHeapify(int i) {
int left = leftChild(i);
int right = rightChild(i);
int smallest = i;
if (left < size &&
(heap[left].getPriority() < heap[i].getPriority() ||
(heap[left].getPriority() == heap[i].getPriority() &&
heap[left].getArrivalTime() < heap[i].getArrivalTime()))) {
smallest = left;
}
if (right < size &&
(heap[right].getPriority() < heap[smallest].getPriority() ||
(heap[right].getPriority() == heap[smallest].getPriority() &&
heap[right].getArrivalTime() < heap[smallest].getArrivalTime()))) {
smallest = right;
}
if (smallest != i) {
swap(i, smallest);
minHeapify(smallest);
}
}
// Get the process with the highest priority (root of the heap).
Process top() { return heap[0]; }
// Check if the priority queue is empty.
bool isEmpty() { return size == 0; }
};
// Define a class for a regular priority queue.
class Priority_queue {
private:
vector<Process> heap; // The heap data structure
int size; // Current size of the queue
int capacity; // Maximum capacity of the queue
// Helper functions for heap operations
int parent(int i) { return (i - 1) / 2; }
int leftChild(int i) { return 2 * i + 1; }
int rightChild(int i) { return 2 * i + 2; }
void swap(int i, int j) {
Process temp = heap[i];
heap[i] = heap[j];
heap[j] = temp;
}
public:
// Constructor to initialize the priority queue.
Priority_queue(int capacity) {
this->capacity = capacity;
this->size = 0;
this->heap = vector<Process>(capacity);
}
// Insert a process into the priority queue based on its arrival time.
void insert(Process process) {
if (size >= capacity) {
cout << "Heap is full, cannot insert." << endl;
return;
}
size++;
int i = size - 1;
heap[i] = process;
while (i != 0 && heap[parent(i)].getArrivalTime() > heap[i].getArrivalTime()) {
swap(i, parent(i));
i = parent(i);
}
}
// Extract the process with the smallest arrival time.
Process extractMin() {
if (size <= 0) {
cout << "Heap is empty." << endl;
return Process(0, 0, "", 0, 0);
}
if (size == 1) {
size--;
return heap[0];
}
Process root = heap[0];
heap[0] = heap[size - 1];
size--;
minHeapify(0);
return root;
}
// Maintain the min-heap property.
void minHeapify(int i) {
int left = leftChild(i);
int right = rightChild(i);
int smallest = i;
if (left < size && heap[left].getArrivalTime() < heap[i].getArrivalTime())
smallest = left;
if (right < size && heap[right].getArrivalTime() < heap[smallest].getArrivalTime())
smallest = right;
if (smallest != i) {
swap(i, smallest);
minHeapify(smallest);
}
}
// Get the process with the smallest arrival time (root of the heap).
Process top() { return heap[0]; }
// Check if the priority queue is empty.
bool isEmpty() { return size == 0; }
};
// Define a class for a simple queue.
class Queue {
private:
int front, rear, size;
int capacity;
vector<Process> queue;
public:
// Constructor to initialize the queue.
Queue(int capacity) {
this->capacity = capacity;
this->front = this->size = 0;
this->rear = capacity - 1;
this->queue = vector<Process>(capacity);
}
// Check if the queue is full.
bool isFull() { return (size == capacity); }
// Check if the queue is empty.
bool isEmpty() { return (size == 0); }
// Enqueue a process into the queue.
void enqueue(Process process) {
if (isFull()) {
cout << "Queue is full. Cannot enqueue." << endl;
return;
}
rear = (rear + 1) % capacity;
queue[rear] = process;
size++;
}
// Dequeue a process from the queue.
Process dequeue() {
if (isEmpty()) {
cout << "Queue is empty. Cannot dequeue." << endl;
return Process(0, 0, "", 0, 0);
}
Process process = queue[front];
front = (front + 1) % capacity;
size--;
return process;
}
// Get the front process in the queue.
Process Front() {
if (isEmpty()) {
cout << "Queue is empty." << endl;
return Process(0, 0, "", 0, 0);
}
return queue[front];
}
// Simulate the execution of a process for one second.
void runForOneSec() {
if (isEmpty()) {
cout << "Queue is empty. Cannot Run." << endl;
return;
}
queue[front].setBurstTime(queue[front].getBurstTime() - 1);
queue[front].setCurRunTime(queue[front].getCurRunTime() + 1);
}
};
// Define a class for representing a Gantt Chart entry.
class GrantChart {
public:
int pid; // Process ID
int startTime; // Start time
int endTime; // End time
GrantChart* next; // Pointer to the next entry
// Constructor to initialize a Gantt Chart entry.
GrantChart(int pid, int startTime, int endTime) {
this->pid = pid;
this->startTime = startTime;
this->endTime = endTime;
this->next = nullptr;
}
};
int currentTime;
GrantChart* chart;
vector<int> turnAroundTime;
vector<int> waitingTime;
vector<int> queueEnteringTime;
// Function to execute a process and update the Gantt Chart.
void executeProcess(Process process, int startTime, int endTime) {
chart->next = new GrantChart(process.getPid(), startTime, endTime);
chart = chart->next;
}
// Function to schedule processes using the Round Robin algorithm.
void RoundRobinScheduler(Queue& readyQueue) {
int timeQuantum = 2;
readyQueue.runForOneSec();
Process executingProcess = readyQueue.Front();
int idx = executingProcess.getPid() - 1;
int remainingBurstTime = executingProcess.getBurstTime();
waitingTime[idx] += currentTime - queueEnteringTime[idx];
if (remainingBurstTime == 0) {
currentTime += 1;
executeProcess(executingProcess, currentTime - 1, currentTime);
readyQueue.dequeue();
turnAroundTime[idx] = currentTime - executingProcess.getArrivalTime();
}
else if (executingProcess.getCurRunTime() == timeQuantum) {
currentTime += 1;
readyQueue.dequeue();
readyQueue.enqueue(executingProcess);
executeProcess(executingProcess, currentTime - 1, currentTime);
queueEnteringTime[idx] = currentTime;
executingProcess.setCurRunTime(0);
}
else {
currentTime += 1;
executeProcess(executingProcess, currentTime - 1, currentTime);
queueEnteringTime[idx] = currentTime;
}
}
// Function to schedule processes based on priority.
void priorityScheduler(Priority_queue_using_priority& readyQueue) {
Process process = readyQueue.extractMin();
int remainingBurstTime = process.getBurstTime();
int idx = process.getPid() - 1;
waitingTime[idx] += currentTime - queueEnteringTime[idx];
if (remainingBurstTime <= 1) {
currentTime += 1;
executeProcess(process, currentTime - 1, currentTime);
turnAroundTime[idx] = currentTime - process.getArrivalTime();
} else {
currentTime += 1;
process.setBurstTime(remainingBurstTime - 1);
readyQueue.insert(process);
executeProcess(process, currentTime - 1, currentTime);
queueEnteringTime[idx] = currentTime;
}
}
// Function to schedule processes based on First-Come-First-Serve (FCFS).
void firstComeFirstServeScheduler(Priority_queue& readyQueue) {
Process process = readyQueue.extractMin();
int remainingBurstTime = process.getBurstTime();
int idx = process.getPid() - 1;
waitingTime[idx] += currentTime - queueEnteringTime[idx];
if (remainingBurstTime <= 1) {
currentTime += 1;
executeProcess(process, currentTime - 1, currentTime);
turnAroundTime[idx] = currentTime - process.getArrivalTime();
} else {
currentTime += 1;
process.setBurstTime(remainingBurstTime - 1);
readyQueue.insert(process);
executeProcess(process, currentTime - 1, currentTime);
queueEnteringTime[idx] = currentTime;
}
}
// Function to convert process type (integer) to a string.
string getTypeString(int type) {
switch (type) {
case 1:
return "System";
case 2:
return "Interactive";
case 3:
return "Interactive Editing";
case 4:
return "Batch";
default:
return "Unknown";
}
}
int main() {
int numProcesses;
cin >> numProcesses;
Priority_queue arrivedProcesses(numProcesses);
currentTime = 0;
chart = new GrantChart(-1, 0, 0);
turnAroundTime = vector<int>(numProcesses, 0);
waitingTime = vector<int>(numProcesses, 0);
queueEnteringTime = vector<int>(numProcesses, 0);
GrantChart* headOfChart = chart;
Priority_queue_using_priority systemProcesses(numProcesses);
Queue interactiveProcesses(numProcesses);
Queue interactiveEditingProcesses(numProcesses);
Priority_queue batchProcess(numProcesses);
// Read process information and add them to the arrived processes queue.
for (int i = 0; i < numProcesses; i++) {
int arrivalTime, burstTime, priority, type;
cin >> arrivalTime >> burstTime >> priority >> type;
Process process(i + 1, arrivalTime, getTypeString(type), burstTime, priority);
arrivedProcesses.insert(process);
queueEnteringTime[i] = arrivalTime;
waitingTime[i] = 0;
}
// Main scheduling loop.
while (!arrivedProcesses.isEmpty() || !systemProcesses.isEmpty() || !interactiveProcesses.isEmpty() || !interactiveEditingProcesses.isEmpty() || !batchProcess.isEmpty()) {
while (!arrivedProcesses.isEmpty() && arrivedProcesses.top().getArrivalTime() <= currentTime) {
Process topushed = arrivedProcesses.extractMin();
if (topushed.getType() == "System") systemProcesses.insert(topushed);
else if (topushed.getType() == "Interactive") interactiveProcesses.enqueue(topushed);
else if (topushed.getType() == "Interactive Editing") interactiveEditingProcesses.enqueue(topushed);
else if (topushed.getType() == "Batch") batchProcess.insert(topushed);
}
if (!systemProcesses.isEmpty()) {
priorityScheduler(systemProcesses);
} else if (!interactiveProcesses.isEmpty()) {
RoundRobinScheduler(interactiveProcesses);
} else if (!interactiveEditingProcesses.isEmpty()) {
RoundRobinScheduler(interactiveEditingProcesses);
} else if (!batchProcess.isEmpty()) {
firstComeFirstServeScheduler(batchProcess);
}
else currentTime++;
}
// Print the Gantt Chart.
chart = headOfChart->next;
cout << "GRANT CHART" << endl;
cout << "0";
int prev = 0;
while (chart != nullptr) {
if (prev != chart->startTime) {
cout << " | IDLE | " << chart->startTime;
}
while (chart->next != nullptr && chart->pid == chart->next->pid) {
chart = chart->next;
}
cout << " | P" << chart->pid << " | " << chart->endTime;
prev = chart->endTime;
chart = chart->next;
}
cout << endl;
// Print waiting times for each process and calculate average waiting time.
cout << "Waiting Time For Each Process" << endl;
double sum = 0;
for (int i = 0; i < numProcesses; i++) {
cout << "P" << i + 1 << ": " << waitingTime[i] << endl;
sum += waitingTime[i];
}
cout << "Average Waiting Time: " << sum / numProcesses << endl;
// Print turn around times for each process and calculate average turn around time.
cout << "Turn Around Time Of Each Process" << endl;
sum = 0;
for (int i = 0; i < numProcesses; i++) {
cout << "P" << i + 1 << ": " << turnAroundTime[i] << endl;
sum += turnAroundTime[i];
}
cout << "Average Turn Around Time: " << sum / numProcesses << endl;
return 0;
}
但是,在执行程序时,屏幕上没有输出。谁能帮我解决这个问题并指出我哪里出了问题?
答: 暂无答案
评论