Advertisement
nO_OnE_910

OS process scheduler

Feb 21st, 2016
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 11.76 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6.  
  7. namespace Betriebssysteme
  8. {
  9.     class Program
  10.     {
  11.         static void Main(string[] args)
  12.         {
  13.             /* Prozess       | 1 2 3 4 5 6 7 8
  14.             Bearbeitungszeit | 4 5 6 1 2 3 4 2
  15.             Ankunftszeit     | 1 1 1 1 1 3 4 5 */
  16.             int[,] prozesse = new int[,] { { 4, 1 }, { 5, 1 }, { 6, 1 }, { 1, 1 }, { 2, 1 }, { 3, 3 }, { 4, 4 }, { 2, 5 } };
  17.             int[,] r = roundRobin(prozesse, 3, 2);
  18.             //int[,] r = firstComeFirstServe(prozesse, 3);
  19.  
  20.             // Print:
  21.             for (int j = 0; j < r.GetLength(1); j++)
  22.             {
  23.                 for (int i = 0; i < r.GetLength(0); i++)
  24.                 {
  25.                     Console.Write(r[i, j]);
  26.                     if (i < r.GetLength(0) - 1)
  27.                         Console.Write(", ");
  28.                 }
  29.                 if (j < r.GetLength(1) - 1)
  30.                     Console.Write("\n");
  31.             }
  32.  
  33.             // Press any key to exit
  34.             Console.ReadKey();
  35.         }
  36.  
  37.         /// <summary>
  38.         /// Erzeugt eine Belegungstabelle für eine
  39.         /// Prozesstabelle mit Bearbeitungszeit [0]
  40.         /// und eine Ankunftszeit [1] nach FCFS.
  41.         /// </summary>
  42.         /// <param name="p">Prozesstabelle (0-basiert)</param>
  43.         /// <param name="k">Kernanzahl</param>
  44.         /// <returns>Die Belegungstabelle</returns>
  45.         static int[,] firstComeFirstServe(int[,] p, int k)
  46.         {
  47.             int[,] r = new int[0, k]; // Lege Ergebnistabelle an
  48.             int i = 0;
  49.             while (notEmpty(p)) // Solange Prozesse eingetragen werden müssen
  50.             {
  51.                 r = ResizeArray<int>(r, Math.Max(r.GetLength(0), i + 1), r.GetLength(1)); // Füge Spalte an Tabelle an falls nötig
  52.                 for (int j = 0; j < k; j++)
  53.                 {
  54.                     if (notEmpty(p) && r[i, j] <= 0) // Wenn Zelle leer
  55.                     {
  56.                         r = setNext(r, p, i, j); // Fülle sie
  57.                         p[r[i, j] - 1, 0] = Int32.MaxValue; // Prozess eingetragen
  58.                     }
  59.                 }
  60.                 i++;
  61.             }
  62.             return r;
  63.         }
  64.  
  65.         /// <summary>
  66.         /// Erzeugt eine Belegungstabelle für eine
  67.         /// Prozesstabelle mit Bearbeitungszeit [0]
  68.         /// und eine Ankunftszeit [1] nach Round
  69.         /// Robin.
  70.         /// </summary>
  71.         /// <param name="p">Prozesstabelle (0-basiert)</param>
  72.         /// <param name="k">Kernanzahl</param>
  73.         /// <param name="timeSlice">Zeitscheibe</param>
  74.         /// <returns>Die Belegungstabelle</returns>
  75.         static int[,] roundRobin(int[,] p, int k, int timeSlice)
  76.         {
  77.             int[,] r = new int[0, k]; // Lege Ergebnistabelle an
  78.             List<int[]> list = new List<int[]>(); // Lege Prozessqueue an
  79.             int i = 0;
  80.             while (notEmpty(p) || list.Count > 0) // Solange in der Liste oder der Queue noch Prozesse sind
  81.             {
  82.                 r = ResizeArray<int>(r, Math.Max(r.GetLength(0), i + 2), r.GetLength(1)); // Erweitere das Array um 1 Spalte
  83.                 for (int slice = 0; slice < timeSlice; slice++) // Für jeden Zeitpunkt in diesem Slice
  84.                 {
  85.                     for (int l = p.GetLength(0) - 1; l > -1; l--) // Füge neue Prozesse in die Queue
  86.                         if (p[l, 1] == i + slice + 1)
  87.                         {
  88.                             list.Reverse();
  89.                             list.Add(new int[] { l, p[l, 0] }); // Vorher und nacher wird reversed damit der Prozess am Anfang der Liste steht
  90.                             list.Reverse();
  91.                             p[l, 0] = Int32.MaxValue; // Lösche Prozess aus Liste
  92.                         }
  93.                     for (int j = 0; j < k; j++) // Für jeden Kern
  94.                     {
  95.                         if (list.Count > 0 && r[i + slice, j] <= 0) // Wenn Prozesse in der Queue und Zelle leer
  96.                         {
  97.                             setNextRR(r, list, i + slice, j, slice == 0); // Fülle Zelle
  98.                         }
  99.                     }
  100.                 }
  101.                 i += timeSlice;
  102.             }
  103.             return r;
  104.         }
  105.  
  106.         /// <summary>
  107.         /// Überprüft ob noch Prozesse bearbeitet werden müssen.
  108.         /// </summary>
  109.         /// <param name="p">Prozesstabelle</param>
  110.         /// <returns>true, wenn es einen nicht (fertig) bearbeiteten Prozess gibt</returns>
  111.         static bool notEmpty(int[,] p)
  112.         {
  113.             for (int i = 0; i < p.GetLength(0); i++)
  114.                 if (p[i, 0] != Int32.MaxValue)
  115.                     return true;
  116.             return false;
  117.         }
  118.  
  119.         /// <summary>
  120.         /// Hier wird die nächste Zelle in der Tabelle für
  121.         /// einen bestimmten Kern und einen bestimmten
  122.         /// Zeitpunkt bestimmt, nach FCFS.
  123.         /// </summary>
  124.         /// <param name="r">Die Ergebnistabelle (Das Diagramm)</param>
  125.         /// <param name="p">Die aktuelle Prozessqueue</param>
  126.         /// <param name="t">Der Zeitpunkt (0-basiert)</param>
  127.         /// <param name="k">Der Kern (0-basiert)</param>
  128.         /// <returns>Die veränderte Ergebnistabelle</returns>
  129.         static int[,] setNext(int[,] r, int[,] p, int t, int k)
  130.         {
  131.             int i = -1;
  132.             for (int j = 0; j < p.GetLength(0); j++) // Finde den Prozess p = i mit i minimal
  133.             {
  134.                 if (p[j, 1] - 1 <= t) // Nur wenn der Prozess angekommen ist
  135.                     if (i < 0 || p[i, 1] > p[j, 1])
  136.                         i = j;
  137.             }
  138.             r = ResizeArray<int>(r, Math.Max(r.GetLength(0), t + p[i, 0]), r.GetLength(1)); // Füge für jede Bearbeitungszeit von p eine Spalte an, wenn sie noch nicht existiert
  139.             for (int j = t; j < t + p[i, 0]; j++)
  140.             {
  141.                 r[j, k] = i + 1; // Füge p so lange ein bis fertig bearbeitet
  142.             }
  143.             return r;
  144.         }
  145.  
  146.         /// <summary>
  147.         /// Hier wird die nächste Zelle in der Tabelle für
  148.         /// einen bestimmten Kern und einen bestimmten
  149.         /// Zeitpunkt bestimmt, nach Round Robin.
  150.         /// </summary>
  151.         /// <param name="r">Die Ergebnistabelle (Das Diagramm)</param>
  152.         /// <param name="p">Die aktuelle Prozessqueue</param>
  153.         /// <param name="t">Der Zeitpunkt (0-basiert)</param>
  154.         /// <param name="k">Der Kern (0-basiert)</param>
  155.         /// <param name="firstInSlice">true / false je nachdem ob mit diesem t eine neue Zeitscheibe beginnt</param>
  156.         static void setNextRR(int[,] r, List<int[]> p, int t, int k, bool firstInSlice)
  157.         {
  158.             if (firstInSlice) // Am Anfang müssen wir einen Prozess bestimmen der für diesen Slice geschrieben wird
  159.             {
  160.                 int[] pro = bestProcess(p, t == 0 ? -1 : r[t-1,k], k, r.GetLength(1)); // Hole ersten Prozess
  161.                 r[t, k] = pro[0] + 1; // Schreibe in Grant Diagramm
  162.                 p.Remove(pro); // Lösche aus Warteliste
  163.                 if (--pro[1] > 0) // Nun 1 Bearbeitungszeit weniger
  164.                     p.Add(pro); // Wenn noch bedarf, schreibe wieder rein
  165.             }
  166.             else // Hier nurnoch den gewählten Prozess wiederholen falls noch nicht abgearbeitet
  167.             {
  168.                 int pro = r[t - 1, k];
  169.                 if (pro <= 0)
  170.                 {
  171.                     r[t, k] = pro; // Nichts zu tun
  172.                     return;
  173.                 }
  174.                 int[] pr = null;
  175.                 for (int i = 0; pr == null && i < p.Count; i++) // Finde den Prozess in der Queue um herauszufinden ob er fertig bearbeitet ist
  176.                 {
  177.                     if (p[i][0] == pro - 1)
  178.                         pr = p[i];
  179.                 }
  180.                 if (pr == null)
  181.                 {
  182.                     r[t, k] = 0; // Nichts zu tun
  183.                     return;
  184.                 }
  185.                 r[t, k] = pr[0] + 1; // Schreibe in Ergebnistabelle
  186.                 if (--pr[1] <= 0) // Nun 1 Bearbeitungszeit weniger
  187.                     p.Remove(pr); // Lösche aus Warteliste wenn kein Bedarf mehr
  188.             }
  189.         }
  190.  
  191.         /// <summary>
  192.         /// Wir müssen berücksichtigen, dass der erste Prozess
  193.         /// in der Liste vielleicht nicht der beste ist, den
  194.         /// wir zur Zeit nehmen können. Z.B. Soll immer die
  195.         /// kleinste Zahl zu erst geschrieben werden, außerdem
  196.         /// sollen Kernwechsel minimiert werden.
  197.         /// </summary>
  198.         /// <param name="p">Die aktuelle Prozessqueue</param>
  199.         /// <param name="last">Der Prozess der als letztes in diesem Kern ausgeführt wurde</param>
  200.         /// <param name="kern">Aktueller Kern (0-basiert)</param>
  201.         /// <param name="kernN">Anzahl Kerne</param>
  202.         /// <returns>Der passende Prozess</returns>
  203.         public static int[] bestProcess(List<int[]> p, int last, int kern, int kernN)
  204.         {
  205.             if (kern == kernN - 1)
  206.                 return p[0];
  207.             int[] r = null;
  208.             for (int i = 0; i < p.Count && i < kernN-kern; i++)
  209.             {
  210.                 if (p[i][0] == last-1)
  211.                     return p[i];
  212.                 if (r == null || r[0] > p[i][0])
  213.                     r = p[i];
  214.             }
  215.             return r;
  216.         }
  217.  
  218.         /// <summary>
  219.         /// Verändert die Größe eines 2D-Arrays.
  220.         /// Quelle: Internet
  221.         /// </summary>
  222.         /// <typeparam name="T"></typeparam>
  223.         /// <param name="original"></param>
  224.         /// <param name="rows"></param>
  225.         /// <param name="cols"></param>
  226.         /// <returns></returns>
  227.         static T[,] ResizeArray<T>(T[,] original, int rows, int cols)
  228.         {
  229.             var newArray = new T[rows, cols];
  230.             int minRows = Math.Min(rows, original.GetLength(0));
  231.             int minCols = Math.Min(cols, original.GetLength(1));
  232.             for (int i = 0; i < minRows; i++)
  233.                 for (int j = 0; j < minCols; j++)
  234.                     newArray[i, j] = original[i, j];
  235.             return newArray;
  236.         }
  237.  
  238.         /// <summary>
  239.         /// Löscht eine Zeile aus einem Array.
  240.         /// Quelle: Internet
  241.         /// </summary>
  242.         /// <typeparam name="T"></typeparam>
  243.         /// <param name="originalArray"></param>
  244.         /// <param name="rowToRemove"></param>
  245.         /// <returns></returns>
  246.         public static T[,] TrimArray<T>(T[,] originalArray, int rowToRemove)
  247.         {
  248.             return TrimArray<T>(originalArray, rowToRemove, -1);
  249.         }
  250.  
  251.         /// <summary>
  252.         /// Löscht eine Zeile und eine Spalte aus einem Array.
  253.         /// Quelle: Internet
  254.         /// </summary>
  255.         /// <typeparam name="T"></typeparam>
  256.         /// <param name="originalArray"></param>
  257.         /// <param name="rowToRemove"></param>
  258.         /// <param name="columnToRemove"></param>
  259.         /// <returns></returns>
  260.         public static T[,] TrimArray<T>(T[,] originalArray, int rowToRemove, int columnToRemove)
  261.         {
  262.             T[,] result = new T[originalArray.GetLength(0) - 1, originalArray.GetLength(1) - (columnToRemove == -1 ? 0 : 1)];
  263.  
  264.             for (int i = 0, j = 0; i < originalArray.GetLength(0); i++)
  265.             {
  266.                 if (i == rowToRemove)
  267.                     continue;
  268.                 if (originalArray.GetLength(0) > 1)
  269.                     for (int k = 0, u = 0; k < originalArray.GetLength(1); k++)
  270.                     {
  271.                         if (k == columnToRemove)
  272.                             continue;
  273.  
  274.                         result[j, u] = originalArray[i, k];
  275.                         u++;
  276.                     }
  277.                 j++;
  278.             }
  279.  
  280.             return result;
  281.         }
  282.     }
  283. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement