take code
take code
#include <fstream>
#include <sstream>
#include <string>
#include <queue>
#include <climits>
#include <unistd.h>
#include <cstdlib>
//count processes
int countProcesses(Process* head) {
int processCount = 0;
for (Process* temp = head; temp != nullptr; temp = temp->next) {
processCount++;
}
return processCount;
}
outFile.close();
cout << "Results for algorithm " << algorithmNumber << " written to
'" << outputFile << "' successfully." << endl;
}
if (shortestJob) {
if (shortestJob->startTime == -1) shortestJob->startTime =
currentTime;
shortestJob->remainingBurstTime--;
currentTime++;
if (shortestJob->remainingBurstTime == 0) {
shortestJob->completionTime = currentTime;
shortestJob->turnAroundTime = shortestJob-
>completionTime - shortestJob->arrivalTime;
shortestJob->waitingTime = shortestJob->turnAroundTime
- shortestJob->burstTime;
completed++;
}
} else {
currentTime++;
}
}}
// Priority Scheduling Non-Preemptive
void priorityNonPreemptive(Process* head) {
int processCount = countProcesses(head);
int currentTime = 0, completed = 0;
while (completed < processCount) {
Process* highestPriorityProcess = nullptr;
int highestPriority = INT_MAX;
for (Process* temp = head; temp; temp = temp->next) {
if (temp->arrivalTime <= currentTime && temp-
>remainingBurstTime > 0 && temp->priority < highestPriority) {
highestPriority = temp->priority;
highestPriorityProcess = temp;
}
}
if (highestPriorityProcess) {
highestPriorityProcess->startTime =
(highestPriorityProcess->startTime == -1) ? currentTime :
highestPriorityProcess->startTime;
currentTime += highestPriorityProcess->burstTime;
highestPriorityProcess->remainingBurstTime = 0;
highestPriorityProcess->completionTime = currentTime;
highestPriorityProcess->turnAroundTime = currentTime -
highestPriorityProcess->arrivalTime;
highestPriorityProcess->waitingTime =
highestPriorityProcess->turnAroundTime - highestPriorityProcess-
>burstTime;
completed++;
} else {
currentTime++;
}
}
}
// Round Robin Scheduling
void roundRobin(Process* head, int timeQuantum) {
queue<Process*> readyQueue;
int processCount=countProcesses( head);
int currentTime = 0, completed = 0;
if (current->remainingBurstTime > 0) {
readyQueue.push(current);
} else {
current->completionTime = currentTime;
current->turnAroundTime = current->completionTime -
current->arrivalTime;
current->waitingTime = current->turnAroundTime -
current->burstTime;
completed++;
}
} else {
currentTime++;
}
}
}
// First-Come-First-Serve Scheduling
void firstComeFirstServe(Process* head) {
int currentTime = 0, completed = 0;
current->startTime = currentTime;
currentTime += current->burstTime; // Add burst time to
current time for completion
current->completionTime = currentTime;
current->turnAroundTime = current->completionTime - current-
>arrivalTime;
current->waitingTime = current->turnAroundTime - current-
>burstTime;
completed++;
head = head->next; // Move to the next process in the list
}
}
// Shortest-Job-First Non-Preemptive Scheduling
void sjfNonPreemptive(Process* head) {
int processCount = countProcesses(head);
int currentTime = 0, completed = 0;
// Find the process with the shortest burst time that has
arrived and not yet completed
for (Process* temp = head; temp != nullptr; temp = temp->next)
{
if (temp->arrivalTime <= currentTime && temp-
>remainingBurstTime > 0 && temp->remainingBurstTime < minBurst) {
minBurst = temp->remainingBurstTime;
shortestJob = temp;
}
}
// Find the process with the highest priority that has arrived
and is still pending
for (Process* temp = head; temp; temp = temp->next) {
if (temp->arrivalTime <= currentTime && temp-
>remainingBurstTime > 0 && temp->priority > highestPriority) {
highestPriority = temp->priority;
highestPriorityProcess = temp;
}
}
if (highestPriorityProcess) {
// If it's the first time this process is being executed,
set the start time
highestPriorityProcess->startTime =
(highestPriorityProcess->startTime == -1) ? currentTime :
highestPriorityProcess->startTime;
// Clear output file for a fresh run (only on the first algorithm
call)
static bool firstRun = true;
if (firstRun) {
ofstream outFile(outputFile, ios::trunc); // Clear file content
if (!outFile) {
cerr << "Error: Could not reset output file." << endl;
return;
}
outFile.close();
firstRun = false;
}
switch (algorithm) {
case 1: sjfPreemptive(head); break;
case 2: roundRobin(head, timeQuantum); break;
case 3: sjfNonPreemptive(head); break;
case 4: priorityPreemptive(head); break;
case 5: priorityNonPreemptive(head); break;
case 6: firstComeFirstServe(head); break;
default:
cerr << "Invalid algorithm choice." << endl;
return;
}
void displayUsage() {
cout << "Usage: ./scheduler -t <time_quantum> -f <input_file> -o
<output_file>\n";
cout << " -t <time_quantum> Specify the time quantum for Round
Robin scheduling.\n";
cout << " -f <input_file> Specify the input file containing
process data.\n";
cout << " -o <output_file> Specify the output file to write
results.\n";
exit(EXIT_FAILURE);
}
cout << "Scheduling results have been written to '" << outputFile
<< "' successfully.\n";
return 0;
}
Here’s a simple explanation of the six CPU scheduling algorithms you’ve mentioned:
What it does: The CPU selects the process with the shortest burst time and
completes it before moving to the next process.
Key Point: Once a process starts, it cannot be interrupted even if a shorter job
arrives.
Analogy: Imagine a line at a printer. If you have a 1-page print job and someone else
has a 10-page print job, your print job is completed first, no matter when other jobs
arrive.
What it does: The CPU selects the process with the shortest burst time. If a new
process with a shorter burst time arrives, the CPU switches to it immediately.
Key Point: The current process can be interrupted if a shorter one arrives.
Analogy: Imagine you're assembling sandwiches in a restaurant. If a customer orders
a simple sandwich, you’ll drop your current complex order to quickly finish the
simpler one first.
What it does: A special case of SJF Preemptive, where the CPU always chooses the
process with the least remaining burst time.
Key Point: The decision considers how much time a process has left, not the total
burst time.
Analogy: If you’re cleaning up multiple tasks and a 5-minute task is halfway done,
you'll finish it before starting a new 10-minute task, even if the new task seems
shorter.
What it does: Each process gets a fixed time slice (quantum). If it doesn’t finish, it
moves to the end of the queue, and the next process gets its turn.
Key Point: Fair and time-shared, but processes might take longer to finish.
Analogy: Imagine a teacher giving every student 5 minutes to speak in a debate, then
moving to the next student. If someone’s time runs out, they wait for the next round.
What it does: The CPU selects the process with the highest priority and completes it
before moving to the next.
Key Point: Processes cannot interrupt each other; once started, a process finishes.
Analogy: At an airport, VIPs are served first regardless of when others arrived, but
once a VIP is being served, no one else can interrupt.
6. Priority Scheduling Preemptive
What it does: The CPU selects the process with the highest priority. If a new
process with a higher priority arrives, it interrupts the current one.
Key Point: Current processes can be stopped mid-execution for higher-priority tasks.
Analogy: If a VIP arrives at an airport while another is being served, the staff pauses
the current service to immediately attend to the new VIP.