Requisito previo: Programación Round Robin con hora de llegada como 0
Se utiliza un algoritmo de programación por turnos para programar el proceso de manera justa para cada trabajo en un intervalo de tiempo o cantidad y la interrupción del trabajo si no se completa para entonces, el trabajo viene después del otro trabajo que llega en el tiempo cuántico que hace estos programar de manera justa.
Nota:
- Round-robin es de naturaleza cíclica, por lo que no se produce inanición.
- Round-robin es una variante de la programación por orden de llegada
- No se da prioridad, se da especial importancia a ningún proceso o tarea
- La programación de RR también se conoce como programación de división de tiempo
ventajas:
- Cada proceso es atendido por la CPU durante un tiempo fijo, por lo que la prioridad es la misma para cada uno
- El hambre no ocurre debido a su naturaleza cíclica.
Desventajas:
- El rendimiento depende del tiempo cuántico.
- Si queremos dar prioridad a algún proceso, no podemos.
Proceso | Hora de llegada | Tiempo quemado | Tiempo de finalización | Tiempo de vuelta | Tiempo de espera |
---|---|---|---|---|---|
P1 | 0 | 5 | 12 | 12 | 7 |
P2 | 1 | 4 | 11 | 10 | 6 |
P3 | 2 | 2 | 6 | 4 | 2 |
P4 | 3 | 1 | 9 | 6 | 5 |
El tiempo cuántico es 2 , esto significa que cada proceso solo se ejecuta durante 2 unidades de tiempo a la vez.
Cómo calcular estas requests de proceso: –
- Tome el proceso que ocurre primero y comience a ejecutar el proceso (solo para el tiempo cuántico).
- Compruebe si ha llegado alguna otra solicitud de proceso. Si llega una solicitud de proceso durante el tiempo cuántico en el que se está ejecutando otro proceso, agregue el nuevo proceso a la cola Listo
- Después de que haya pasado el tiempo cuántico, verifique si hay procesos en la cola Listo. Si la cola de listos está vacía, continúe con el proceso actual. Si la cola no está vacía y el proceso actual no está completo, agregue el proceso actual al final de la cola lista.
- Tome el primer proceso de la cola Listo y comience a ejecutarlo (las mismas reglas)
- Repita todos los pasos anteriores del 2 al 4
- Si el proceso está completo y la cola de listos está vacía, entonces la tarea está completa
Después de todo esto obtenemos los tres tiempos que son:
- Tiempo de finalización: el tiempo que tarda un proceso en completarse.
- Turn Around Time: tiempo total que el proceso existe en el sistema. (hora de finalización – hora de llegada).
- Tiempo de Espera: tiempo total de espera para su completa ejecución. (tiempo de vuelta – tiempo de ráfaga).
Cómo implementar en un lenguaje de programación
1. Declare arrival[], burst[], wait[], turn[] arrays and initialize them. Also declare a timer variable and initialize it to zero. To sustain the original burst array create another array (temp_burst[]) and copy all the values of burst array in it. 2. To keep a check we create another array of bool type which keeps the record of whether a process is completed or not. we also need to maintain a queue array which contains the process indices (initially the array is filled with 0). 3. Now we increment the timer variable until the first process arrives and when it does, we add the process index to the queue array 4. Now we execute the first process until the time quanta and during that time quanta, we check whether any other process has arrived or not and if it has then we add the index in the queue (by calling the fxn. queueUpdation()). 5. Now, after doing the above steps if a process has finished, we store its exit time and execute the next process in the queue array. Else, we move the currently executed process at the end of the queue (by calling another fxn. queueMaintainence()) when the time slice expires. 6. The above steps are then repeated until all the processes have been completely executed. If a scenario arises where there are some processes left but they have not arrived yet, then we shall wait and the CPU will remain idle during this interval.
A continuación se muestra la implementación del enfoque anterior:
(En aras de la simplicidad, asumimos que los tiempos de llegada se ingresan de forma ordenada)
C++
C++
//C++ Program for implementing //Round Robin Algorithm //code by sparsh_cbs #include <iostream> using namespace std; void queueUpdation(int queue[],int timer,int arrival[],int n, int maxProccessIndex){ int zeroIndex; for(int i = 0; i < n; i++){ if(queue[i] == 0){ zeroIndex = i; break; } } queue[zeroIndex] = maxProccessIndex + 1; } void queueMaintainence(int queue[], int n){ for(int i = 0; (i < n-1) && (queue[i+1] != 0) ; i++){ int temp = queue[i]; queue[i] = queue[i+1]; queue[i+1] = temp; } } void checkNewArrival(int timer, int arrival[], int n, int maxProccessIndex,int queue[]){ if(timer <= arrival[n-1]){ bool newArrival = false; for(int j = (maxProccessIndex+1); j < n; j++){ if(arrival[j] <= timer){ if(maxProccessIndex < j){ maxProccessIndex = j; newArrival = true; } } } //adds the incoming process to the ready queue //(if any arrives) if(newArrival) queueUpdation(queue,timer,arrival,n, maxProccessIndex); } } //Driver Code int main(){ int n,tq, timer = 0, maxProccessIndex = 0; float avgWait = 0, avgTT = 0; cout << "\nEnter the time quanta : "; cin>>tq; cout << "\nEnter the number of processes : "; cin>>n; int arrival[n], burst[n], wait[n], turn[n], queue[n], temp_burst[n]; bool complete[n]; cout << "\nEnter the arrival time of the processes : "; for(int i = 0; i < n; i++) cin>>arrival[i]; cout << "\nEnter the burst time of the processes : "; for(int i = 0; i < n; i++){ cin>>burst[i]; temp_burst[i] = burst[i]; } for(int i = 0; i < n; i++){ //Initializing the queue and complete array complete[i] = false; queue[i] = 0; } while(timer < arrival[0]) //Incrementing Timer until the first process arrives timer++; queue[0] = 1; while(true){ bool flag = true; for(int i = 0; i < n; i++){ if(temp_burst[i] != 0){ flag = false; break; } } if(flag) break; for(int i = 0; (i < n) && (queue[i] != 0); i++){ int ctr = 0; while((ctr < tq) && (temp_burst[queue[0]-1] > 0)){ temp_burst[queue[0]-1] -= 1; timer += 1; ctr++; //Checking and Updating the ready queue until all the processes arrive checkNewArrival(timer, arrival, n, maxProccessIndex, queue); } //If a process is completed then store its exit time //and mark it as completed if((temp_burst[queue[0]-1] == 0) && (complete[queue[0]-1] == false)){ //turn array currently stores the completion time turn[queue[0]-1] = timer; complete[queue[0]-1] = true; } //checks whether or not CPU is idle bool idle = true; if(queue[n-1] == 0){ for(int i = 0; i < n && queue[i] != 0; i++){ if(complete[queue[i]-1] == false){ idle = false; } } } else idle = false; if(idle){ timer++; checkNewArrival(timer, arrival, n, maxProccessIndex, queue); } //Maintaining the entries of processes //after each premption in the ready Queue queueMaintainence(queue,n); } } for(int i = 0; i < n; i++){ turn[i] = turn[i] - arrival[i]; wait[i] = turn[i] - burst[i]; } cout << "\nProgram No.\tArrival Time\tBurst Time\tWait Time\tTurnAround Time" << endl; for(int i = 0; i < n; i++){ cout<<i+1<<"\t\t"<<arrival[i]<<"\t\t" <<burst[i]<<"\t\t"<<wait[i]<<"\t\t"<<turn[i]<<endl; } for(int i =0; i< n; i++){ avgWait += wait[i]; avgTT += turn[i]; } cout<<"\nAverage wait time : "<<(avgWait/n) <<"\nAverage Turn Around Time : "<<(avgTT/n); return 0; }
C#
// C# program to implement Round Robin // Scheduling with different arrival time using System; class GFG { public static void roundRobin(String[] p, int[] a, int[] b, int n) { // result of average times int res = 0; int resc = 0; // for sequence storage String seq = ""; // copy the burst array and arrival array // for not effecting the actual array int[] res_b = new int[b.Length]; int[] res_a = new int[a.Length]; for (int i = 0; i < res_b.Length; i++) { res_b[i] = b[i]; res_a[i] = a[i]; } // critical time of system int t = 0; // for store the waiting time int[] w = new int[p.Length]; // for store the Completion time int[] comp = new int[p.Length]; while (true) { Boolean flag = true; for (int i = 0; i < p.Length; i++) { // these condition for if // arrival is not on zero // check that if there come before qtime if (res_a[i] <= t) { if (res_a[i] <= n) { if (res_b[i] > 0) { flag = false; if (res_b[i] > n) { // make decrease the b time t = t + n; res_b[i] = res_b[i] - n; res_a[i] = res_a[i] + n; seq += "->" + p[i]; } else { // for last time t = t + res_b[i]; // store comp time comp[i] = t - a[i]; // store wait time w[i] = t - b[i] - a[i]; res_b[i] = 0; // add sequence seq += "->" + p[i]; } } } else if (res_a[i] > n) { // is any have less arrival time // the coming process then execute // them for (int j = 0; j < p.Length; j++) { // compare if (res_a[j] < res_a[i]) { if (res_b[j] > 0) { flag = false; if (res_b[j] > n) { t = t + n; res_b[j] = res_b[j] - n; res_a[j] = res_a[j] + n; seq += "->" + p[j]; } else { t = t + res_b[j]; comp[j] = t - a[j]; w[j] = t - b[j] - a[j]; res_b[j] = 0; seq += "->" + p[j]; } } } } // now the previous process // according to ith is process if (res_b[i] > 0) { flag = false; // Check for greaters if (res_b[i] > n) { t = t + n; res_b[i] = res_b[i] - n; res_a[i] = res_a[i] + n; seq += "->" + p[i]; } else { t = t + res_b[i]; comp[i] = t - a[i]; w[i] = t - b[i] - a[i]; res_b[i] = 0; seq += "->" + p[i]; } } } } // if no process is come on the critical else if (res_a[i] > t) { t++; i--; } } // for exit the while loop if (flag) { break; } } Console.WriteLine("name ctime wtime"); for (int i = 0; i < p.Length; i++) { Console.WriteLine(" " + p[i] + "\t" + comp[i] + "\t" + w[i]); res = res + w[i]; resc = resc + comp[i]; } Console.WriteLine("Average waiting time is " + (float)res / p.Length); Console.WriteLine("Average compilation time is " + (float)resc / p.Length); Console.WriteLine("Sequence is like that " + seq); } // Driver Code public static void Main(String[] args) { // name of the process String[] name = { "p1", "p2", "p3", "p4" }; // arrival for every process int[] arrivaltime = { 0, 1, 2, 3 }; // burst time for every process int[] bursttime = { 10, 4, 5, 3 }; // quantum time of each process int q = 3; // cal the function for output roundRobin(name, arrivaltime, bursttime, q); } } // This code is contributed by Rajput-Ji
Java
//JAVA Program for implementing //Round Robin Algorithm // code by Sparsh_cbs import java.util.*; public class RoundRobin{ private static Scanner inp = new Scanner(System.in); //Driver Code public static void main(String[] args){ int n,tq, timer = 0, maxProccessIndex = 0; float avgWait = 0, avgTT = 0; System.out.print("\nEnter the time quanta : "); tq = inp.nextInt(); System.out.print("\nEnter the number of processes : "); n = inp.nextInt(); int arrival[] = new int[n]; int burst[] = new int[n]; int wait[] = new int[n]; int turn[] = new int[n]; int queue[] = new int[n]; int temp_burst[] = new int[n]; boolean complete[] = new boolean[n]; System.out.print("\nEnter the arrival time of the processes : "); for(int i = 0; i < n; i++) arrival[i] = inp.nextInt(); System.out.print("\nEnter the burst time of the processes : "); for(int i = 0; i < n; i++){ burst[i] = inp.nextInt(); temp_burst[i] = burst[i]; } for(int i = 0; i < n; i++){ //Initializing the queue and complete array complete[i] = false; queue[i] = 0; } while(timer < arrival[0]) //Incrementing Timer until the first process arrives timer++; queue[0] = 1; while(true){ boolean flag = true; for(int i = 0; i < n; i++){ if(temp_burst[i] != 0){ flag = false; break; } } if(flag) break; for(int i = 0; (i < n) && (queue[i] != 0); i++){ int ctr = 0; while((ctr < tq) && (temp_burst[queue[0]-1] > 0)){ temp_burst[queue[0]-1] -= 1; timer += 1; ctr++; //Updating the ready queue until all the processes arrive checkNewArrival(timer, arrival, n, maxProccessIndex, queue); } if((temp_burst[queue[0]-1] == 0) && (complete[queue[0]-1] == false)){ turn[queue[0]-1] = timer; //turn currently stores exit times complete[queue[0]-1] = true; } //checks whether or not CPU is idle boolean idle = true; if(queue[n-1] == 0){ for(int k = 0; k < n && queue[k] != 0; k++){ if(complete[queue[k]-1] == false){ idle = false; } } } else idle = false; if(idle){ timer++; checkNewArrival(timer, arrival, n, maxProccessIndex, queue); } //Maintaining the entries of processes after each premption in the ready Queue queueMaintainence(queue,n); } } for(int i = 0; i < n; i++){ turn[i] = turn[i] - arrival[i]; wait[i] = turn[i] - burst[i]; } System.out.print("\nProgram No.\tArrival Time\tBurst Time\tWait Time\tTurnAround Time" + "\n"); for(int i = 0; i < n; i++){ System.out.print(i+1+"\t\t"+arrival[i]+"\t\t"+burst[i] +"\t\t"+wait[i]+"\t\t"+turn[i]+ "\n"); } for(int i =0; i< n; i++){ avgWait += wait[i]; avgTT += turn[i]; } System.out.print("\nAverage wait time : "+(avgWait/n) +"\nAverage Turn Around Time : "+(avgTT/n)); } public static void queueUpdation(int queue[],int timer,int arrival[],int n, int maxProccessIndex){ int zeroIndex = -1; for(int i = 0; i < n; i++){ if(queue[i] == 0){ zeroIndex = i; break; } } if(zeroIndex == -1) return; queue[zeroIndex] = maxProccessIndex + 1; } public static void checkNewArrival(int timer, int arrival[], int n, int maxProccessIndex,int queue[]){ if(timer <= arrival[n-1]){ boolean newArrival = false; for(int j = (maxProccessIndex+1); j < n; j++){ if(arrival[j] <= timer){ if(maxProccessIndex < j){ maxProccessIndex = j; newArrival = true; } } } if(newArrival) //adds the index of the arriving process(if any) queueUpdation(queue,timer,arrival,n, maxProccessIndex); } } public static void queueMaintainence(int queue[], int n){ for(int i = 0; (i < n-1) && (queue[i+1] != 0) ; i++){ int temp = queue[i]; queue[i] = queue[i+1]; queue[i+1] = temp; } } }
Javascript
<script> const queueUpdation = (queue, timer, arrival, n, maxProccessIndex) => { let zeroIndex; for (let i = 0; i < n; i++) { if (queue[i] == 0) { zeroIndex = i; break; } } queue[zeroIndex] = maxProccessIndex + 1; } const queueMaintainence = (queue, n) => { for (let i = 0; (i < n - 1) && (queue[i + 1] != 0); i++) { let temp = queue[i]; queue[i] = queue[i + 1]; queue[i + 1] = temp; } } const checkNewArrival = (timer, arrival, n, maxProccessIndex, queue) => { if (timer <= arrival[n - 1]) { let newArrival = false; for (let j = (maxProccessIndex + 1); j < n; j++) { if (arrival[j] <= timer) { if (maxProccessIndex < j) { maxProccessIndex = j; newArrival = true; } } } //adds the incoming process to the ready queue //(if any arrives) if (newArrival) queueUpdation(queue, timer, arrival, n, maxProccessIndex); } } //Driver Code let n = 4; let tq = 2; let timer = 0; let maxProccessIndex = 0; let avgWait = 0; let avgTT = 0; const wait = []; const turn = []; const queue = []; const temp_burst = []; const complete = []; const arrival = [0, 1, 2, 3]; const burst = [5, 4, 2, 1]; for (let i = 0; i < n; i++) { temp_burst[i] = burst[i]; } for (let i = 0; i < n; i++) { //Initializing the queue and complete array complete[i] = false; queue[i] = 0; } while (timer < arrival[0]) //Incrementing Timer until the first process arrives timer++; queue[0] = 1; while (true) { let flag = true; for (let i = 0; i < n; i++) { if (temp_burst[i] != 0) { flag = false; break; } } if (flag) break; for (let i = 0; (i < n) && (queue[i] != 0); i++) { let ctr = 0; while ((ctr < tq) && (temp_burst[queue[0] - 1] > 0)) { temp_burst[queue[0] - 1] -= 1; timer += 1; ctr++; // Checking and Updating the ready queue until all the processes arrive checkNewArrival(timer, arrival, n, maxProccessIndex, queue); } // If a process is completed then store its exit time // and mark it as completed if ((temp_burst[queue[0] - 1] == 0) && (complete[queue[0] - 1] == false)) { //turn array currently stores the completion time turn[queue[0] - 1] = timer; complete[queue[0] - 1] = true; } // checks whether or not CPU is idle let idle = true; if (queue[n - 1] == 0) { for (let i = 0; i < n && queue[i] != 0; i++) { if (complete[queue[i] - 1] == false) { idle = false; } } } else idle = false; if (idle) { timer++; checkNewArrival(timer, arrival, n, maxProccessIndex, queue); } //Maintaining the entries of processes //after each premption in the ready Queue queueMaintainence(queue, n); } } for (let i = 0; i < n; i++) { turn[i] = turn[i] - arrival[i]; wait[i] = turn[i] - burst[i]; } console.log(`Time Quanta : ${tq}`); console.log(`Number of Processes : ${n}`); console.log(`Arrival Time of Processes : ${arrival}`); console.log(`Burst Time of Processes : ${burst}`); console.log("\nProgram No.\tArrival Time\tBurst Time\tWait Time\tTurnAround Time\n"); for (let i = 0; i < n; i++) { console.log(`${i + 1}\t\t\t ${arrival[i]}\t\t\t ${burst[i]}\t\t\t\t ${wait[i]} \t\t\t\t ${turn[i]} \n`); } for (let i = 0; i < n; i++) { avgWait += wait[i]; avgTT += turn[i]; } console.log(`\nAverage wait time : ${avgWait / n}`); console.log(`\nAverage Turn Around Time : ${avgTT / n}`); // This code is contributed by akashish_. </script>
Producción:
Enter the time quanta : 2 Enter the number of processes : 4 Enter the arrival time of the processes : 0 1 2 3 Enter the burst time of the processes : 5 4 2 1 Program No. Arrival Time Burst Time Wait Time TurnAround Time 1 0 5 7 12 2 1 4 6 10 3 2 2 2 4 4 3 1 5 6 Average wait time : 5 Average Turn Around Time : 8
En caso de cualquier consulta o problema con el código, escríbalo en la sección de comentarios.
Nota: Se podría hacer una versión ligeramente optimizada del código implementado anteriormente utilizando la estructura de datos de cola de la siguiente manera:
C++
#include <bits/stdc++.h> using namespace std; struct Process { int pid; int arrivalTime; int burstTime; int burstTimeRemaining; // the amount of CPU time remaining after each execution int completionTime; int turnaroundTime; int waitingTime; bool isComplete; bool inQueue; }; /* * At every time quantum or when a process has been executed before the time quantum, * check for any new arrivals and push them into the queue */ void checkForNewArrivals(Process processes[], const int n, const int currentTime, queue<int> &readyQueue) { for (int i = 0; i < n; i++) { Process p = processes[i]; // checking if any processes has arrived // if so, push them in the ready Queue. if (p.arrivalTime <= currentTime && !p.inQueue && !p.isComplete) { processes[i].inQueue = true; readyQueue.push(i); } } } /* * Context switching takes place at every time quantum * At every iteration, the burst time of the processes in the queue are handled using this method */ void updateQueue(Process processes[], const int n, const int quantum, queue<int> &readyQueue, int ¤tTime, int &programsExecuted) { int i = readyQueue.front(); readyQueue.pop(); // if the process is going to be finished executing, // ie, when it's remaining burst time is less than time quantum // mark it completed and increment the current time // and calculate its waiting time and turnaround time if (processes[i].burstTimeRemaining <= quantum) { processes[i].isComplete = true; currentTime += processes[i].burstTimeRemaining; processes[i].completionTime = currentTime; processes[i].waitingTime = processes[i].completionTime - processes[i].arrivalTime - processes[i].burstTime; processes[i].turnaroundTime = processes[i].waitingTime + processes[i].burstTime; if (processes[i].waitingTime < 0) processes[i].waitingTime = 0; processes[i].burstTimeRemaining = 0; // if all the processes are not yet inserted in the queue, // then check for new arrivals if (programsExecuted != n) { checkForNewArrivals(processes, n, currentTime, readyQueue); } } else { // the process is not done yet. But it's going to be pre-empted // since one quantum is used // but first subtract the time the process used so far processes[i].burstTimeRemaining -= quantum; currentTime += quantum; // if all the processes are not yet inserted in the queue, // then check for new arrivals if (programsExecuted != n) { checkForNewArrivals(processes, n, currentTime, readyQueue); } // insert the incomplete process back into the queue readyQueue.push(i); } } /* * Just a function that outputs the result in terms of their PID. */ void output(Process processes[], const int n) { double avgWaitingTime = 0; double avgTurntaroundTime = 0; // sort the processes array by processes.PID sort(processes, processes + n, [](const Process &p1, const Process &p2) { return p1.pid < p2.pid; }); for (int i = 0; i < n; i++) { cout << "Process " << processes[i].pid << ": Waiting Time: " << processes[i].waitingTime << " Turnaround Time: " << processes[i].turnaroundTime << endl; avgWaitingTime += processes[i].waitingTime; avgTurntaroundTime += processes[i].turnaroundTime; } cout << "Average Waiting Time: " << avgWaitingTime / n << endl; cout << "Average Turnaround Time: " << avgTurntaroundTime / n << endl; } /* * This function assumes that the processes are already sorted according to their arrival time */ void roundRobin(Process processes[], int n, int quantum) { queue<int> readyQueue; readyQueue.push(0); // initially, pushing the first process which arrived first processes[0].inQueue = true; int currentTime = 0; // holds the current time after each process has been executed int programsExecuted = 0; // holds the number of programs executed so far while (!readyQueue.empty()) { updateQueue(processes, n, quantum, readyQueue, currentTime, programsExecuted); } } int main() { int n, quantum; cout << "Enter the number of processes: "; cin >> n; cout << "Enter time quantum: "; cin >> quantum; Process processes[n + 1]; for (int i = 0; i < n; i++) { cout << "Enter arrival time and burst time of each process " << i + 1 << ": "; cin >> processes[i].arrivalTime; cin >> processes[i].burstTime; processes[i].burstTimeRemaining = processes[i].burstTime; processes[i].pid = i + 1; cout << endl; } // stl sort in terms of arrival time sort(processes, processes + n, [](const Process &p1, const Process &p2) { return p1.arrivalTime < p2.arrivalTime; }); roundRobin(processes, n, quantum); output(processes, n); return 0; }
Enter the number of processes: 4 Enter time quantum: 2 Enter the arrival time and burst time of each process: 0 5 1 4 2 2 3 1 Process 1: Waiting Time: 7 Turnaround Time: 12 Process 2: Waiting Time: 6 Turnaround Time: 10 Process 3: Waiting Time: 2 Turnaround Time: 4 Process 4: Waiting Time: 5 Turnaround Time: 6 Average Waiting Time: 5 Average Turnaround Time: 8
Publicación traducida automáticamente
Artículo escrito por Abhisheksharmaabhi y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA