DEV Community

Leo
Leo

Posted on • Updated on

Planificación de Procesos (C++)

main

/*
AUTOR:    Neftalí Leobardo Vázquez Castillo
CURSO:    Sistemas Operativos
PROGRAMA: Planificación de Procesos
FECHA:    19 de Abril del 2024
*/

#include <iostream>
#include "so.hpp"

int main(){

 int n, op;
    cout << "\n\t Planificacion de procesos - Sistemas Operativos";
    cout << "\n\n\tIngrese el numero total de procesos a trabajar: ";
    while (!(cin >> n)) {
        cin.clear();
        cin.ignore(100, '\n');
        system("cls");
        cout << "\n\tError: Entrada invalida. \n\tPor favor, ingrese un numero entero para el total de procesos: ";
    }
    system("cls");
    process so(n);
    so.addProcess();
    system("cls");
    so.print();
    do {
    so.Menu();
    while (!(cin >> op)) {
        cin.clear();
        cin.ignore(100, '\n');
        system("cls");
        cout << "\n\tError: Entrada invalida. \n\tPor favor, ingrese un numero entero para seleccionar proceso.\n\n";
        so.Menu();
    }
    system("cls");
    switch(op){
    case 1:
    so.FIFO();
    break;
    case 2:
    so.SJF();
    break;
    case 3:
    so.Prioridad();
    break;
    case 4:
    so.RoundRobin();
    break;
    case 5:
    so.print();
    break;
    case 6:
    cout << "\n\tRecuerda que puedes volver a calcular cuando gustes." << endl;
    break;
    default:
    cout << "\n\tIngresa una opcion valida." << endl;
    break;
    }
    } while (op != 6);

return 0;
}
Enter fullscreen mode Exit fullscreen mode

so.cpp

#include "so.hpp"

  process::node::node(string i, int t, int q) {     // Se declara nodo: String para ID y Enteros para tiempo y prioridad. 
      _id = i;
      _time = t;
      _priority = q;
      _next = nullptr;      // Inicia apuntador next en vacío.
  }

  process::process(int c){      // Se construye lista enlazada vacía y se especifica su capacidad.

      n = c;
      head = nullptr;
      tail = nullptr;
  }

  process::~process(){          // Destructor, se encarga de limpiar la memoria al término del programa.

      while(head != nullptr) {

          node *p = head;
          head = head -> next();
          delete p;
      }
  }


  void process::print(){        // Muestra el contenido Original de la lista.

    cout << "\n\t Planificacion de procesos - Sistemas Operativos";
    cout << "\n\n\t Procesos registrados (ID // Tiempo // Prioridad)\n\n" << endl;
    cout << "\t";
      node *p = head;
      while(p != nullptr){
      cout << " | " << p -> id() << " " << p -> tme() << " " << p -> prty() << " | ";
      p = p -> next();
      }
     cout << endl;
}



void process::addProcess() {    // Función para crear y organizar nodos en la lista Original, pidiendo los datos al usuario.

     for(int i = 0; i < n ; i++){   // Se piden los datos y se guardan en 3 variables.
        string a;
        int b, c;
        cout << "ID: ";
        cin >> a;
        cout << "Tiempo: ";
        cin >> b;
        cout << "Prioridad: ";
        cin >> c;

        node *p = new node(a, b, c);    // Se crea nodo con la información brindada
        if (empty()) {                  // Si la lista está vacía, cabeza y cola apuntan al mismo nodo.
            head = p;
            tail = p;
      }else{                            // Si la lista no está vacía, se forma el nuevo nodo después del último.
            tail -> next(p);
            tail = p;
        }
        s++;
 cout << "\n\tProceso agregado." << endl;
}
}


void process::Menu() {                  // Se muestra el menú de opciones para seleccionar.

     cout << "\n\t\tMENU DE PROCESOS\n" << endl;
     cout << "\t1. FIFO" << endl;
     cout << "\t2. SJF" << endl;
     cout << "\t3. Prioridad (Dinamica)" << endl;
     cout << "\t4. Round-Robin" << endl;
     cout << "\t5. Ver procesos registrados" << endl;
     cout << "\t6. Salir" << endl;
     cout << "\n\tIngrese su opcion: ";

}



int process::calcQ() {          // Función para calcular Quantum.

    int x = 0;                  // Se inicializa contador en 0.
      node *p = head;           // Se crea nuevo nodo para recorrer la lista.
      while(p != nullptr) {     // Se recorre la lista completa.
          x += p -> tme();      // Se suman los tiempos de todos los nodos.
          p = p -> next();      // Avanza al sig nodo.
      }
    return x/n;                 // Se calcula el Quantum dividiendo la suma total entre el número de nodos.
}

  void process::FIFO() {        // Función para primeras entradas, primeras salidas.

    cout << "\n\t Planificacion de procesos - Sistemas Operativos";
    cout << "\n\n\t FIFO (Primera Entrada, Primera Salida)\n" << endl;

        node *c_head = nullptr;                     //Se genera copia de la lista original para no afectar los datos.
        node *c_tail = nullptr;
      node *p = head;

        while (p != nullptr) {

            node *r = new node(p -> id(), p -> tme(), p -> prty());
            if (c_head == nullptr) {
                c_head = r;
                c_tail = r;
            } else {
                c_tail -> next(r);
                c_tail = r;
            }
            p = p -> next();
        }
                                                    // Se calcula FIFO. 
      float tR = 0, tRT = 0;                        // Se declaran contadores flotantes para Tiempo de Respuesta y Tiempo de Respuesta Total.
      cout << "\n\tId //" << " Tiempo de ejecucion //" << " Tiempo de retorno //"<< " Procesos restantes (ID Tiempo)" << endl;
      p = c_head;                                   // Se usa la copia de la lista
      while (p != nullptr) {                        // Se recorre la lista completa

          tR += p -> tme();                         // Se suma el tiempo de respuesta de cada nodo.
          tRT += tR;                                // El tiempo de respuesta se suma al tiempo de respuesta total.
          cout << "\t"<< p -> id() << "\t\t"<< p -> tme()<< "\t\t"<< tR<< "\t\t";       // Se muestra el ID, el tiempo del nodo y el tiempo de respuesta.
          node *t = p -> next();                    // Se genera nuevo nodo para recorrer el restante de la lista para poder graficar.
      while(t != nullptr){                          // Se recorre el resto de la lista mostrando los procesos restantes.
      cout << " | " << t -> id() << " " << t -> tme() << " | ";     // Se muestran los procesos restantes: ID y Tiempo de cada nodo.
      t = t -> next();                              // Se avanza en lo que resta de la graficación de la lista.
            }
          cout << endl;
          p = p -> next();                          // Siguiente nodo de la lista que se está trabajando.
      }
      p = c_head;                                   // Se elimina la copia de la lista que se generó al principio de la función.
      while (p != nullptr) {                        // Se recorre la copia de la lista completa.
          node *xd = p;                             // Se crea nuevo nodo igual al actual.
          p = p -> next();                          // El apuntador se mueve al siguiente nodo.
          delete xd;                                // Se elimina el nodo creado, limpiando la memoria.
      }

      cout << "\n\tTiempo promedio: "<< (float)tRT/n<< endl;
  }

  void process::SJF() {
        node *c_head = nullptr;                     //Se genera copia de la lista original para no afectar los datos.
        node *c_tail = nullptr;
        node *p = head;

        while (p != nullptr) {

            node *r = new node(p -> id(), p -> tme(), p -> prty());
            if (c_head == nullptr) {
                c_head = r;
                c_tail = r;
            } else {
                c_tail -> next(r);
                c_tail = r;
            }
            p = p -> next();
        }
        p = c_head;                                 // Se usa la copia de la lista.
      while (p != nullptr) {                        // Se usa un ciclo para recorrer la lista.
          node *q = p -> next();                    // Se crea un nodo después del actual para comparar los tiempos entre procesos.
          while (q != nullptr) {                    // Se usa un ciclo para recorrer la lista con el nuevo nodo.

              if (q -> tme() < p -> tme()) {        // Se compara si el nodo siguiente es menor que el nodo actual, se ejecuta el ciclo.

                  string idx = p -> id();           // Se usan auxiliares para guardar la información al intercambiarla.
                  int tmex = p -> tme();
                  int prtyx = p -> prty();

                  p -> setid(q -> id());            // Se cambia el nodo actual por el nodo siguiente.
                  p -> settme(q -> tme());
                  p -> setprty(q -> prty());

                  q -> setid(idx);                  // Se guardan en el nodo siguiente los datos del nodo actual.
                  q -> settme(tmex);
                  q -> setprty(prtyx);

              }
              q = q -> next();                      // Apuntador siguiente avanza.
          }
          p = p -> next();                          // Apuntador actual avanza.
      }

    cout << "\n\t Planificacion de procesos - Sistemas Operativos";
    cout << "\n\n\t SJF (Tiempo mas corto primero)\n" << endl;
    node *z = c_head;                               // Se usa la copia de la lista
      float tR = 0, tRT = 0;                        // Se declaran contadores flotantes para Tiempo de Respuesta y Tiempo de Respuesta Total.
      cout << "\n\tId //" << " Tiempo de ejecucion //" << " Tiempo de retorno //"<< " Procesos restantes (ID Tiempo)" << endl;
      while (z != nullptr) {

          tR += z -> tme();
          tRT += tR;
          cout << "\t"<< z -> id() << "\t\t"<< z -> tme()<< "\t\t"<< tR<< "\t\t";
          node *t = z -> next();
      while(t != nullptr){
      cout << " | " << t -> id() << " " << t -> tme() << " | ";
      t = t -> next();
            }
          cout << endl;
          z = z -> next();
      }
        //Se elimina copia de la lista
      p = c_head;
      while (p != nullptr) {
          node *xd = p;
          p = p -> next();
          delete xd;
      }
      cout << "\n\tTiempo promedio: "<< (float)tRT/n<< endl;
  }

  void process::Prioridad() {
        //Se genera copia de la lista
      node *c_head = nullptr;
        node *c_tail = nullptr;
        node *p = head;

        while (p != nullptr) {

            node *r = new node(p -> id(), p -> tme(), p -> prty());
            if (c_head == nullptr) {
                c_head = r;
                c_tail = r;
            } else {
                c_tail -> next(r);
                c_tail = r;
            }
            p = p -> next();
        }
      //se ordena por prioridad
        p = c_head;
      while (p != nullptr) {
          node *q = p -> next();
          while (q != nullptr) {

              if (q -> prty() > p -> prty()) {

                  string idx = p -> id();
                  int tmex = p -> tme();
                  int prtyx = p -> prty();

                  p -> setid(q -> id());
                  p -> settme(q -> tme());
                  p -> setprty(q -> prty());

                  q -> setid(idx);
                  q -> settme(tmex);
                  q -> setprty(prtyx);

              }
              q = q -> next();
          }
          p = p -> next();
      }

    cout << "\n\t Planificacion de procesos - Sistemas Operativos";
    cout << "\n\n\t Prioridad Dinamica (Prioridad de mayor a menor usando Quantum)\n" << endl;
        //Se calcula prioridar por cuantum
      node *r = c_head;
      float tR = 0, tRT = 0;
      int Q = calcQ();
      cout << "\n\tId //" << " Tiempo de ejecucion //" << " Prioridad //" << " Tiempo de retorno //" << " Procesos restantes (ID Tiempo Prioridad)" << endl;

      while (r != nullptr) {

            if (r -> tme() <= Q) {

          tR += r -> tme();
          tRT += tR;
          cout << "\t"<< r -> id() << "\t\t"<< r -> tme()<< "\t\t"<< r -> prty()<< "\t\t"<< tR<< "\t\t";
          node *t = r -> next();
      while(t != nullptr){
      cout << " | " << t -> id() << " " << t -> tme() << " " << t -> prty() << " | ";
      t = t -> next();
            }
          cout << endl;
          r = r -> next();
            }else{
            tR += Q;
            cout << "\t"<< r -> id() << " pendiente     "<< r -> tme()<< "\t\t"<< r -> prty()<< "\t\t"<< tR<< "\t\t";
            r -> settme(r -> tme() - Q);
            r -> setprty(r -> prty() - 1);

            node *t2 = r;
        while (t2->next() != nullptr && t2->next()->prty() >= r->prty()) {
            t2 = t2->next();
        }
        if (t2 != r) {
            node *temp = r->next();
            r->next(t2->next());
            t2->next(r);
            r = temp;
        } else {
            r = r->next();
        }
        node *t = r;
      while(t != nullptr){
      cout << " | " << t -> id() << " " << t -> tme() << " " << t -> prty() << " | ";
      t = t -> next();
            }
            cout << endl;
            }
      }
        //Se elimina copia de la lista
        p = c_head;
      while (p != nullptr) {
          node *xd = p;
          p = p -> next();
          delete xd;
      }
      cout << "\n\tTiempo promedio: "<< (float)tRT/n<< endl;
      cout << "\n\tQuantum: "<< Q<< endl;
  }

  void process::RoundRobin() {

    cout << "\n\t Planificacion de procesos - Sistemas Operativos";
    cout << "\n\n\t Round Robin (Primera Entrada, Primera salida usando Quantum)\n" << endl;
        //Se genera copia de la lista
      node *c_head = nullptr;
      node *c_tail = nullptr;
      node *r = head;

        while (r != nullptr) {

            node *m = new node(r -> id(), r -> tme(), r -> prty());
            if (c_head == nullptr) {
                c_head = m;
                c_tail = m;
            } else {
                c_tail -> next(m);
                c_tail = m;
            }
            r = r -> next();
        }

                //Se calcula Round Robin
      r = c_head;
      float tR = 0, tRT = 0;
      int Q = calcQ();
      cout << "\n\tId //" << " Tiempo de ejecucion //" << " Tiempo de retorno //" << " Procesos restantes (ID Tiempo)" << endl;

      while (r != nullptr) {

            if (r -> tme() <= Q) {

          tR += r -> tme();
          tRT += tR;
          cout << "\t"<< r -> id() << "\t\t"<< r -> tme()<< "\t\t"<< tR<< "\t\t";
          node *t = r -> next();
      while(t != nullptr){
      cout << " | " << t -> id() << " " << t -> tme()  << " | ";
      t = t -> next();
            }
          cout << endl;
          r = r -> next();
            }else{
            tR += Q;
            cout << "\t"<< r -> id() << " pendiente     "<< r -> tme()<< "\t\t"<< tR<< "\t\t";
            r -> settme(r -> tme() - Q);

            node *t2 = r;
        while (t2->next() != nullptr) {
            t2 = t2->next();
        }
        if (t2 != r) {
            node *temp = r->next();
            r->next(t2->next());
            t2->next(r);
            r = temp;
        } 
        node *t = r;
      while(t != nullptr){
      cout << " | " << t -> id() << " " << t -> tme() << " | ";
      t = t -> next();
            }
            cout << endl;
            }
      }
        //Se elimina copia de la lista
      r = c_head;
      while (r != nullptr) {
          node *xd = r;
          r = r -> next();
          delete xd;
      }
      cout << "\n\tTiempo promedio: "<< (float)tRT/n<< endl;
      cout << "\n\tQuantum: "<< Q<< endl;
  }

Enter fullscreen mode Exit fullscreen mode

so.hpp

#ifndef so_hpp
#define so_hpp

#include <iostream>
#include <assert.h>
using namespace std;

class process { // Clase proceso, así se llama la lista enlazada con la que trabajamos.

    class node {    // Clase nodo con atributos id, tiempo y prioridad.

  string _id;
  int _time;
  int _priority;
  node *_next;

  public:

    node(string i, int t, int q);

  string id() const { return _id; } //cual es el id.
  int tme() const { return _time; } //cual es el tiempo.
  int prty() const { return _priority; } //cual es la prioridad.
  node *next() const { return _next; } // cual es el siguiente apuntador.
  void next(node *p) { _next = p; } // cambia el siguiente apuntador.

    //cambiar datos 
  void setid(string x) { _id = x; } 
  void settme(int x) { _time = x; } 
  void setprty(int x) { _priority = x; }
  };

  int n; // Capacity of process/node.
  int s; // Size of process/node.

  node *head; // First item in queue.
  node *tail; // Last item in queue.

public:
    // Constructor y destructor.
  process(int);
  ~process();
    // Funciones básicas para conocer la lista enlasada (capacidad, tamaño, si está llena o vacía).
  int capacity() const { return n; }
  int size() const { return s; }

  bool full() const { return s==n; }
  bool empty() const { return s==0; }

    // Funciones para la ejecución de programa, se desarrollan en so.cpp.
  void print();

  void addProcess();
  void Menu();
  int calcQ();

  void FIFO();
  void SJF();
  void Prioridad();
  void RoundRobin();

};

#endif /* so_hpp */ //dev.to/imnotleo/planificacion-de-procesos-c-3m5k
Enter fullscreen mode Exit fullscreen mode

Top comments (0)