diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..bb879da5 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,59 @@ +{ + "C_Cpp_Runner.cCompilerPath": "gcc", + "C_Cpp_Runner.cppCompilerPath": "g++", + "C_Cpp_Runner.debuggerPath": "gdb", + "C_Cpp_Runner.cStandard": "", + "C_Cpp_Runner.cppStandard": "", + "C_Cpp_Runner.msvcBatchPath": "C:/Program Files/Microsoft Visual Studio/VR_NR/Community/VC/Auxiliary/Build/vcvarsall.bat", + "C_Cpp_Runner.useMsvc": false, + "C_Cpp_Runner.warnings": [ + "-Wall", + "-Wextra", + "-Wpedantic", + "-Wshadow", + "-Wformat=2", + "-Wcast-align", + "-Wconversion", + "-Wsign-conversion", + "-Wnull-dereference" + ], + "C_Cpp_Runner.msvcWarnings": [ + "/W4", + "/permissive-", + "/w14242", + "/w14287", + "/w14296", + "/w14311", + "/w14826", + "/w44062", + "/w44242", + "/w14905", + "/w14906", + "/w14263", + "/w44265", + "/w14928" + ], + "C_Cpp_Runner.enableWarnings": true, + "C_Cpp_Runner.warningsAsError": false, + "C_Cpp_Runner.compilerArgs": [], + "C_Cpp_Runner.linkerArgs": [], + "C_Cpp_Runner.includePaths": [], + "C_Cpp_Runner.includeSearch": [ + "*", + "**/*" + ], + "C_Cpp_Runner.excludeSearch": [ + "**/build", + "**/build/**", + "**/.*", + "**/.*/**", + "**/.vscode", + "**/.vscode/**" + ], + "C_Cpp_Runner.useAddressSanitizer": false, + "C_Cpp_Runner.useUndefinedSanitizer": false, + "C_Cpp_Runner.useLeakSanitizer": false, + "C_Cpp_Runner.showCompilationTime": false, + "C_Cpp_Runner.useLinkTimeOptimization": false, + "C_Cpp_Runner.msvcSecureNoWarnings": false +} \ No newline at end of file diff --git a/UA1/examen/dev_22/ejercicio2/EstadoPlantas.java b/UA1/examen/dev_22/ejercicio2/EstadoPlantas.java new file mode 100644 index 00000000..0fb3a9f7 --- /dev/null +++ b/UA1/examen/dev_22/ejercicio2/EstadoPlantas.java @@ -0,0 +1,21 @@ +public class EstadoPlantas extends Thread{ + private int detector; + public EstadoPlantas() { + detector = (int) (Math.random() * 5); + } + + @Override + public void run() { + try { + Thread.sleep((long) (Math.random() * 3000 + 1000)); // Esperar un tiempo aleatorio entre 1 y 3 segundos + } catch (InterruptedException e) { + e.printStackTrace(); + } + double medicion = Math.random() * 100; // Generar una medición aleatoria entre 0 y 100 + long tiempo = System.currentTimeMillis(); // Obtener el tiempo actual en milisegundos + System.out.printf("Sensor Estado de las plantas nº %d: Medición %.2f, Tiempo: %d%n", detector, medicion, tiempo); + } + + + +} diff --git a/UA1/examen/dev_22/ejercicio2/Humedad.java b/UA1/examen/dev_22/ejercicio2/Humedad.java new file mode 100644 index 00000000..c99a5917 --- /dev/null +++ b/UA1/examen/dev_22/ejercicio2/Humedad.java @@ -0,0 +1,20 @@ +public class Humedad extends Thread { + private double humedad; + + public Humedad() { + this.humedad = Math.random() * 100; // Valor aleatorio recogido por el sensor + } + + @Override + public void run() { + try { + Thread.sleep((long) (Math.random() * 2000) + 1000); // Duerme entre 1 y 3 segundos + } catch (InterruptedException e) { + e.printStackTrace(); + } + + System.out.println("Sensor de humedad: " + humedad + " % - Lectura realizada en " + System.currentTimeMillis()); + } + + +} diff --git a/UA1/examen/dev_22/ejercicio2/Temperatura.java b/UA1/examen/dev_22/ejercicio2/Temperatura.java new file mode 100644 index 00000000..36652580 --- /dev/null +++ b/UA1/examen/dev_22/ejercicio2/Temperatura.java @@ -0,0 +1,23 @@ +public class Temperatura extends Thread { + private String sensor; + + public Temperatura(String sensor) { + this.sensor = sensor; + + } + + @Override + public void run() { + while (true) { + double temperatura = (Math.random() * 50) + 1; + try { + Thread.sleep((long) (Math.random() * 3000 + 1000)); // Esperar un tiempo aleatorio entre 1 y 3 segundos + } catch (InterruptedException e) { + e.printStackTrace(); + } + + System.out.printf("%s de temperatura: %.2f grados Celsius, leída en %d ms%n", sensor, temperatura, System.currentTimeMillis()); + } + } + +} diff --git a/UA1/examen/dev_22/ejercicio2/ua1ex1p2.java b/UA1/examen/dev_22/ejercicio2/ua1ex1p2.java new file mode 100644 index 00000000..be05c8af --- /dev/null +++ b/UA1/examen/dev_22/ejercicio2/ua1ex1p2.java @@ -0,0 +1,58 @@ +/* +PARTE PRÁCTICA 2/2 + +Se ha decidido implantar un huerto en un centro público, y se han instalado varios sensores ESP32 para monitorizar la temperatura, la humedad del suelo y el estado de las plantas en distintas áreas del huerto. Se requiere un sistema en Java que simule la lectura de estos sensores de manera concurrente para obtener los datos en tiempo real. + +Tu tarea es diseñar una solución que simule el monitoreo de estos sensores usando hilos en Java. El sistema debe realizar lo siguiente: + +Crear tres hilos para simular los sensores: uno para la temperatura, otro para la humedad del suelo y otro para el estado de las plantas. + +Cada sensor (hilo) debe: + +Generar un valor aleatorio para la medición correspondiente. +Dormir durante un tiempo aleatorio entre 1 y 3 segundos para simular la espera entre lecturas. +Imprimir el valor generado con un mensaje que indique qué sensor hizo la lectura y en qué momento (puedes usar System.currentTimeMillis() para esto). +Los datos de los sensores deben ser leídos de manera concurrente. + +El programa debe ejecutarse durante 10 ciclos de medición (10 iteraciones por sensor). + +Mejora opcional: Implementa una forma de detener todos los sensores después de que hayan hecho las 10 lecturas. + +Funcionalidades Requeridas (FR): +FR1 (2 puntos): Crear un hilo para cada sensor (temperatura, humedad y estado de las plantas). +FR2 (2 puntos): Generar valores aleatorios para cada medición de sensor. +FR3 (2 puntos): Simular la espera de tiempo entre lecturas con Thread.sleep(). +FR4 (2 puntos): Mostrar las lecturas de cada sensor con su correspondiente marca de tiempo. +FR5 (2 puntos): Ejecutar correctamente los 10 ciclos de medición por cada sensor. + +*/ + + + +public class ua1ex1p2 { + public static void main(String[] args) { + + for (int i = 0; i < 10; i++) { // Bucle para que realice 10 ciclos + + Temperatura sensor1 = new Temperatura("Sensor 1"); + sensor1.start(); + + + Humedad humedadThread = new Humedad(); + humedadThread.start(); + + EstadoPlantas detector1 = new EstadoPlantas(); + detector1.start(); + + + try { + Thread.sleep(5000); // Obligo a que cuando finalice un ciclo, espere 5 segundos hasta inciar otro + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + System.out.println("Todos los sensores han finalizado."); + + } +} \ No newline at end of file diff --git a/UA1/examen/dev_22/ua1ex1_teoria.txt b/UA1/examen/dev_22/ua1ex1_teoria.txt new file mode 100644 index 00000000..e04e8bdd --- /dev/null +++ b/UA1/examen/dev_22/ua1ex1_teoria.txt @@ -0,0 +1,50 @@ +PARTE TEÓRICA + +a) Definición de proceso. Ilustra tu solución con un ejemplo. 1 punto. + + Un proceso es una unidad de ejecución que se ejecuta en un sistema operativo. Y este se ejecuta de una manera determinada, ejemplo de ello sería: + - Abrir un navegador y buscar algo en internet. + + +b) Utilizando tus propias palabras, indica la relación entre hilos y procesos. Ilustra tu solución con un ejemplo. 3 puntos. + + Los procesos son como un paquete de mayor tamaño que en su interior se incluyen los hilos. Por ejemplo: Imaginemos una caja de una mudanza, pues el contenido de su interior + serían los hilos y la caja propiamente dicha, serían los procesos. + + +c) Utilizando tus propias palabras, indica las características de la programación concurrente y sus ámbitos de aplicación. 3 puntos. + + Características: + - Interacción: Los procesos se comunican entre si, e intercambian datos y señales. + - Sincronización: Todos los procesos tienen que actuar de forma coordinada, sin solaparse entre ellos. + - Multitarea: Esto nos permite ejecutar varias tareas al mismo tiempo, sin frenar la ejecución de ninguna de ellas. + + Ámbitos de aplicación: + - Desarrollo de SO: Permite gestionar varios procesos y recursos eficientemente. + - Aplicaciones Web y servidores: Si tenemos una web como por ejemplo un E-Commerce, requerimos de que nuestros clientes se registren, pues para poder llevar a cabo esta tarea + sin complicaciones, de que al recibir distintas peticiones al mismo tiempo, nuestro sistema colapse... pues para esto sirve la programación concurrente. + - Juegos y simulaciones: Al igual que el anterior, permite la la ejecución de múltiples elementos en paralelo. + + + + +d) Utilizando tus propias palabras, indica las diferencias entre programación paralela y programación distribuida, sus ventajas e inconvenientes. 3 puntos. + + La programación paralela está enfocada en la ejecución de tareas en el mismo equipo, mientras que la programación distribuida se enfoca en la ejecución de tareas en diferentes equipos. + + Ventajas: + - Ejecución simultanea y menos tiempo de espera en la ejecución (programación paralela). + - Posibilidad de compartir datos y recursos, además de una mayor flexibilidad y disponibilidad (programación distribuida). + + Desventajas: + - Compiladores y sistemas complejos, mayor consumo de energía y complejidad en los accesos a datos (programación paralela). + - Problemas de comunicación entre equipos, y problemas de seguridad (programación distribuida). + + + + +Notas: + +El nombre del fichero .txt a entregar debe ser: examen\dev_X\ua1ex1_teoria.txt , es decir, el fichero ua1ex1_teoria.txt debe estar ubicado en tu carpeta examen\dev_X\ + +No entregues tu solución, hasta que no se indique por parte del profesorado. \ No newline at end of file diff --git a/UA1/examen/dev_22/ua1ex1p1c.c b/UA1/examen/dev_22/ua1ex1p1c.c new file mode 100644 index 00000000..d20ca462 --- /dev/null +++ b/UA1/examen/dev_22/ua1ex1p1c.c @@ -0,0 +1,66 @@ +/* +PARTE PRÁCTICA 1/2 + +FR1: Haz un programa en C que genere una estructura de procesos con un PADRE y 3 HIJOS, del mismo padre se entiende - 2 puntos +FR2: Visualiza por cada hijo su identificador (si es el hijo 1, 2 ó 3), su PID y el del padre, utilizando para ello una función definida por ti a la que llamen los procesos hijos - 2 puntos +FR3: Justo antes de finalizar el programa PADRE, se debe imprimir por pantalla el PID del padre de todos una única vez. Debe hacerlo el programa PADRE - 2 puntos +FR4: Implementa el control de errores - 2 puntos +FR5: Documenta y estructura el código - 2 puntos + + +Para evitar complicaciones con máquinas virtuales, si lo prefieres puedes utilizar el compilador online: https://www.onlinegdb.com/online_c_compiler + +Notas: + +Los comentarios (descriptivos y concisos) en el código ... siempre son bien. +Los nombres de las variables autodescriptivos ... siempre son bien. +Las impresión por pantalla, correctamente indentada y verticalmente espaciada ... siempre es bien. +Los warnings del presente ... son los errores del futuro. +El nombre del fichero .c a entregar debe ser: examen\dev_X\ua1ex1p1.c , es decir, el fichero ua1ex1.cdebe estar ubicado en tu carpeta dev_X\ + +No entregues tu solución, hasta que no se indique por parte del profesorado. +*/ + +#include +#include +#include + + +void hijos (int id) { + pid_t Padre_pid = getppid(); + pid_t pid = getpid(); + hijos(id); + printf("Hijo %d = \n Pid padre %d: Pid hijo %d: \n ", id, Padre_pid, pid); + } + +int main() +{ + int pid1, pid2, pid3; + + pid1 = fork(); + + if (pid1 == 0) + { + hijos(1); + exit(0); + } + + pid2 = fork(); + + if (pid2 == 0) + { + hijos(2); + exit(0); + } + + pid3 = fork(); + + if (pid3 == 0) + { + hijos(3); + exit(0); + } + + return 0; +} + diff --git a/UA1/tareas/dev_0/ua1tarea1.c b/UA1/tareas/dev_0/ua1tarea1.c deleted file mode 100644 index 1b2cfd02..00000000 --- a/UA1/tareas/dev_0/ua1tarea1.c +++ /dev/null @@ -1 +0,0 @@ -Ya os gustaría \ No newline at end of file diff --git a/UA1/tareas/dev_22/UA1tarea1/ua1tarea1.c b/UA1/tareas/dev_22/UA1tarea1/ua1tarea1.c new file mode 100644 index 00000000..33374345 --- /dev/null +++ b/UA1/tareas/dev_22/UA1tarea1/ua1tarea1.c @@ -0,0 +1,34 @@ +#include +#include +#include +int main() +{ + pid_t pid, Padre_pid; + int nota; //Nota es el numero que pediremos despues al usuario + printf ("Introduce un numero\n"); + scanf ("%d", ¬a); //Pedimos el numero con el que trabajaremos mas tarde + + pid = fork(); + //Designamos ambos procesos y el fork creara ambos y hara de pid el proceso padre + + if (pid == -1) //Ha ocurrido un error creando el proceso padre + { + printf ("No se ha podido crear el proceso PADRE"); + exit (-1); + } + + if (pid == 0) //Nos encontramos en el Proceso padre + { + nota-=5;//El proceso padre debe restar 5 y mostrar el resultado + printf("Soy el proceso PADRE:\n\t Mi valor habiendo restando 5 es de %d.\n", + nota); + } + else //Nos encontramos en el proceso hijo + { + wait (NULL); //espera de la finalizacion del proceso padre + nota+=4; //El proceso hijo suma 4 + printf("Soy el proceso HIJO \n\t Mi valor habiendo sumado 4 es de %d.\n", + nota); + } + return(0); +} \ No newline at end of file diff --git a/UA1/tareas/dev_22/UA1tarea1/ua1tarea1.test.c b/UA1/tareas/dev_22/UA1tarea1/ua1tarea1.test.c new file mode 100644 index 00000000..75eaa012 --- /dev/null +++ b/UA1/tareas/dev_22/UA1tarea1/ua1tarea1.test.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include + +int main() { + return 0; +} + +void test_handle_input_zero() { + int pipefd[2]; + pipe(pipefd); + pid_t pid = fork(); + + if (pid == 0) { + // Child process + close(pipefd[0]); // Close unused read end + dup2(pipefd[1], STDOUT_FILENO); // Redirect stdout to pipe + close(pipefd[1]); // Close write end after redirect + + // Simulate input value 0 + FILE *input = fopen("input.txt", "w"); + fprintf(input, "0\n"); + fclose(input); + freopen("input.txt", "r", stdin); + + execl("./ua1tarea1", "./ua1tarea1", NULL); + exit(0); + } else { + // Parent process + close(pipefd[1]); // Close unused write end + wait(NULL); // Wait for child process to finish + + char buffer[128]; + read(pipefd[0], buffer, sizeof(buffer)); + close(pipefd[0]); + + // Check output for both parent and child processes + if (strstr(buffer, "Soy el proceso PADRE:\n\t Mi valor habiendo restando 5 es de -5.\n") && + strstr(buffer, "Soy el proceso HIJO \n\t Mi valor habiendo sumado 4 es de -1.\n")) { + printf("Test passed: Correctly handled input value of 0\n"); + } else { + printf("Test failed: Incorrect handling of input value of 0\n"); + } + } +} diff --git a/UA1/tareas/dev_22/UA1tarea2/cadenaCaracteres.java b/UA1/tareas/dev_22/UA1tarea2/cadenaCaracteres.java new file mode 100644 index 00000000..8b42e962 --- /dev/null +++ b/UA1/tareas/dev_22/UA1tarea2/cadenaCaracteres.java @@ -0,0 +1,29 @@ +import java.util.Scanner; + +public class CadenaCaracteres extends Thread { + + public void run() { + System.out.println("Inicialización del hilo:"); + String resultado; + resultado = funcadena(); + System.out.println("El resultado es: " + resultado); + System.out.println("Fin del hilo."); + } + + public String funcadena(){ + Scanner scanner = new Scanner(System.in); + System.out.print("Ingrese una cadena de caracteres: "); + String cadena = ""; + boolean validador = false; + do { + String texto = scanner.nextLine(); + if (texto.equals("*")) { + validador = true; + } else { + cadena += texto + "\n "; + } + } while (!validador); + scanner.close(); + return cadena; + } +} diff --git a/UA1/tareas/dev_22/UA1tarea2/ua1tarea2.java b/UA1/tareas/dev_22/UA1tarea2/ua1tarea2.java new file mode 100644 index 00000000..8a69084a --- /dev/null +++ b/UA1/tareas/dev_22/UA1tarea2/ua1tarea2.java @@ -0,0 +1,8 @@ +import java.util.Scanner; + +public class ua1tarea2 { + public static void main(String[] args) { + CadenaCaracteres cadena = new CadenaCaracteres(); + cadena.start(); + } +} diff --git a/UA1/tareas/dev_22/UA1tarea3/Main.java b/UA1/tareas/dev_22/UA1tarea3/Main.java new file mode 100644 index 00000000..69c6ac1c --- /dev/null +++ b/UA1/tareas/dev_22/UA1tarea3/Main.java @@ -0,0 +1,22 @@ + +public class Main { + + public static void main(String[] args) { + System.out.println("Ingresa los argumentos de entrada:"); + + if (args.length < 1) { + System.exit(1); + } + + String argumento = args[0]; + + if (argumento.matches("-?\\d+")) { + int numero = Integer.parseInt(argumento); + if (numero < 0) { + System.exit(3); + } + } else { + System.exit(2); + } + } +} diff --git a/UA1/tareas/dev_22/ua1tarea3/Argumentos.java b/UA1/tareas/dev_22/ua1tarea3/Argumentos.java new file mode 100644 index 00000000..62430082 --- /dev/null +++ b/UA1/tareas/dev_22/ua1tarea3/Argumentos.java @@ -0,0 +1,35 @@ +public class Argumentos { + public static void main(String[] args) { + + if (args.length < 1) { + System.out.println("Error! Por favor ingrese al menos un argumento."); + return; + } + + if { + ProcessBuilder pb = new ProcessBuilder("java", "Main", args[0]); + Process pr = ProcessBuilder.start(); + int exitCode = pr.waitFor(); + + switch (exitCode) { + case 0: + System.out.println("El argumento ingresado es correcto y es entero no negativo."); + break; + case 1: + System.out.println("No hay argumentos."); + break; + case 2: + System.out.println("El argumento ingresado es una cadena."); + break; + case 3: + System.out.println("El argumento ingresado es un numero entero menor a 0."); + break; + default: + System.out.println("Codigo de salida inesperado: " + exitCode); + + } else (Exception e) { + System.out.println("Error iniciando el proceso: " + e.getMessage()); + } + + } +} \ No newline at end of file diff --git a/UA2/examen/ejercicio1/dev_22/ua1ex1.txt b/UA2/examen/ejercicio1/dev_22/ua1ex1.txt new file mode 100644 index 00000000..757cb80e --- /dev/null +++ b/UA2/examen/ejercicio1/dev_22/ua1ex1.txt @@ -0,0 +1,88 @@ +Conceptos básicos sobre hilos (1 punto): + +a) Define qué es un hilo en Java y cómo se relaciona con la multitarea. + + Un hilo en Java es como una tarea, la cual, nos ayuda al funcionamiento de la multitarea, o mejor dicho, el multihilo. + Esta tarea funciona en segundo plano, mientras que el main corre en primer plano, también puede no ejecutarse en segundo plano + si la bloqueas con un sleep. + + +b) Menciona dos diferencias entre la interfaz Runnable y la clase Thread. + + La clase Thread, es una clase la cual extiende de un hilo, este se marca con "extend Thread", + mientras que la interfaz Runnable, es una interfaz la cual se marca con "implement Runnable. + + Otra diferencia sería que la clase Thread, se le puede implementar un método run(), mientras que en la + Runnable, no. + +Sincronización (1 punto): + +a) Explica qué es la sincronización de hilos y por qué es necesaria en Java. + + La sincronización de hilos se puede conseguir con una función denomida, por ejemplo, "public synchronized void", + esta función, no permite que dos hilos accedan a la misma variable al mismo tiempo, sino que, obliga a que + uno termine su ejecución para que el otro pueda proceder a la suya, dando así un resultado, pues más correcto. + + Un ejemplo sería una práctica que hicimos de agregar dinero a un banco, algo por el estilo, y por ejemplo, se podía ver + como, cuando no añadías el synchronized, las introducciones de dinero y salidas actuaban como querían, mientras que al ponerlo + estas eran como más secuenciales, es decir, aparecía primero dinero en el banco, luego el ingreso y finalmente el total. + + + +b) ¿Qué problemas pueden surgir si no se sincronizan adecuadamente los hilos? + + Como he comentando anteriormente, si no se sincronizan adecuadamente los hilos, se pueden producir problemas como, + por ejemplo, que el dinero de las salidas y entradas pues no salgan correctamente, sino que van como quieren sin respetar un orden + ya que no espera a que acabe un hilo para que empiece otro. + + + +Estados de un hilo (1 punto): + +a) Nombra y describe brevemente los principales estados de un hilo en su ciclo de vida. + + El ciclo de vida sería: + 1. Creacion del hilo. + 2. Ejecucion del mismo. + 3. Pausa del hilo (si se desea). + 4. Muerte del hilo. + + + +b) ¿Qué método en Java se utiliza para pausar un hilo por un tiempo específico? + + Para pausar un hilo se puede usar un sleep, el método sería "Thread.sleep()" y entre paréntesis pones los milisegundos + que quieras que este se frene, por ejemplo si son 3 segundos, pues al cambio serían 3000 milisegundos. + + + +Bloques sincronizados y monitores (1 punto): + +a) ¿Qué es un monitor en Java? + + +b) Explica cómo se utiliza el bloque synchronized para garantizar acceso exclusivo a un recurso. + + Se pone el synchronized antes de la función que se quiere que sea exclusiva, por ejemplo, "public synchronized void ". + + +Métodos avanzados en hilos (1 punto): + +a) ¿Qué diferencia existe entre los métodos wait(), notify(), y notifyAll() en Java? + + Los métodos wait(), notify() y notifyAll() son utilizados para hacer que un hilo, espere a ser avisado por otro, + para que pueda seguir con su ejecución. El método wait() hace que el propio hilo espere a ser notificado, el método notify() + notifica a otro hilo para que este se ejecute y por último, el método notifyAll() notifica a todos los hilos que estén esperando. + +b) Explica un caso práctico donde utilizarías estos métodos para resolver un problema de concurrencia. + + Quiero simular el tipico movil o cacharro de los bares para mandar la comanda a cocina, para ello, se necesita que el hilo + el cual se encarga de mandar la comanda, espere a que el hilo que se encarga del pedido termine, para que pueda seguir con + la comanda, pues para eso usaria el método wait(), el cual, me va a hacer que el hilo que se encarga del pedido termine, + para que pueda seguir con la comanda, y el método notify(), para que el hilo que se encarga de la comanda, pueda proceder a + su ejecución. + + Y el metodo notifyAll(), pues en este ejemplo no me serviría, pero si alomejor necesitara que en vez de que vaya a cocina + vaya tambíen a la barra, pues puede ser que en vez de utilizar notify() a secas, usara notifyAll(). + + diff --git a/UA2/examen/ejercicio2/dev_22/ua2ex2/src/ua2ex2.java b/UA2/examen/ejercicio2/dev_22/ua2ex2/src/ua2ex2.java new file mode 100644 index 00000000..b9791f6b --- /dev/null +++ b/UA2/examen/ejercicio2/dev_22/ua2ex2/src/ua2ex2.java @@ -0,0 +1,185 @@ +/** +Feedback JD: 12/12/2024 +Buen trabajo Francisco. + +Problemas y áreas de mejora: + +Condiciones de espera mal aplicadas: + En producir, el bucle while (!(contador == capacidad)) nunca permite a los productores esperar; debería ser while (contador == capacidad). + Lo mismo ocurre en consumir, donde while (!(contador == 0)) debe cambiar a while (contador == 0). + Esto genera un comportamiento inesperado donde wait() no se invoca en las condiciones adecuadas. + +Errores de flujo en los métodos: + wait() se ejecuta fuera del bucle, lo que puede generar fallos o un comportamiento indefinido si el estado del buffer cambia antes de la espera. + +Producción/consumo único por ejecución: + Los métodos producir y consumir no están diseñados para trabajar en un bucle continuo dentro del hilo (e.g., producción/consumo repetitiva), limitando el propósito del programa. + +Falta de control de excepciones robusto: + Las excepciones son manejadas con un RuntimeException, lo cual no proporciona suficiente información para depuración en un entorno real. + + +**/ + +/** + * @file ua2ex2.java + * + * @brief Aplicacion q produce y consume caracteres almacenados en un array + * + * Esta aplicacion alamacenará un array de los caracteres producidos por la clase Productor + * en otra clase Buffer, y la clase Consumidor, se dedicará a extraerlos y procesarlos. + */ + + + + +import java.util.Random; + +/** + * @brief Almacena el array de caracteres + * + * Recibe el caracter producido por la clase Productor y lo almacena, + * como máximo almacenará 10 caracteres, ya que asi se ha establecido en + * la Aplicacion Principal (ua2ex2). + * + * @class Buffer + */ + +class Buffer { + + private char[] buffer; + private int capacidad; + private int indiceEscritura = 0; + private int indiceLectura = 0; + private int contador = 0; + + /** + * @brief El constructor sirve para inicializar el buffer con una capacidad (la cual se especifica en ua2ex2). + * + * @param capacidad es el tamaño máximo del buffer (mas adelante se verá q es 10) + */ + + public Buffer(int capacidad) { + this.capacidad = capacidad; + this.buffer = new char[capacidad]; + } + + /** + * @brief Añade un caracter al buffer si hay espacio disponible y espera si este está lleno. + * + * @param c es la variable que se añadirá al buffer + * + */ + + public synchronized void producir(char c) throws InterruptedException { + while (!(contador == capacidad)) { + buffer[indiceEscritura] = c; + indiceEscritura = (indiceEscritura + 1) % capacidad; + contador++; + System.out.println(indiceEscritura + ". Se ha añadido un caracter: " + c + " y la capacidad actual de la cola está en: " + contador + "/" + capacidad ); + notifyAll(); + } + wait(); + } + + /** + * @brief Extrae un carácter del buffer si hay elementos disponibles y espera si este está lleno. + * + * @return Devuelve el caracter extraído del buffer + */ + + public synchronized char consumir() throws InterruptedException { + char c = buffer[indiceLectura]; + while (!(contador == 0)) { + indiceLectura = (indiceLectura + 1) % capacidad; + contador--; + System.out.println(indiceLectura + ". Se ha eliminado un caracter: " + c + " y la capacidad actual de la cola está en: " + contador + "/" + capacidad ); + notifyAll(); + + } + wait(); + + return c; + } +} + +/** + * @brief Genera caracteres aleatorios + * + * La clase Productor simula un hilo que genera caracteres aleatorios desde la A-Z y los almacena en el buffer. + * + * @class Productor + */ + + +class Productor extends Thread { + + private Buffer buffer; + private Random random = new Random(); + + /** + * @brief El constructor sirve para inicializar el Productor haciendo referencia al Buffer compartido. + * + * @param buffer que es el objeto buffer compartido anterior + */ + + public Productor (Buffer buffer){ + this.buffer = buffer; + + } + + /** + * @brief El método run genera caracteres aleatorios y los añade al buffer y espera un tiempo aleatorio entre 200 ms y 500 ms. + * + */ + + @Override + public void run(){ + try { + char c = (char) (Math.random()*26+'A'); + buffer.producir(c); + Thread.sleep(random.nextInt(200)+300); + + + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + } +} + +class Consumidor extends Thread{ + + private Buffer buffer; + private Random random = new Random(); + + public Consumidor(Buffer buffer) { + this.buffer = buffer; + + } + + @Override + public void run(){ + try { + buffer.consumir(); + Thread.sleep(random.nextInt(300)+400); + + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + } +} + + +public class ua2ex2 { + public static void main(String[] args) { + Buffer buffer = new Buffer(10); + Productor productor = new Productor(buffer); + Consumidor consumidor = new Consumidor(buffer); + + productor.start(); + consumidor.start(); + + } +} diff --git a/UA2/tareas/dev_0/tarea_1/ua2tarea1fr1.java b/UA2/tareas/dev_22/tarea_1/ua2tarea1fr1.java similarity index 100% rename from UA2/tareas/dev_0/tarea_1/ua2tarea1fr1.java rename to UA2/tareas/dev_22/tarea_1/ua2tarea1fr1.java diff --git a/UA2/tareas/dev_0/tarea_1/ua2tarea1fr2.java b/UA2/tareas/dev_22/tarea_1/ua2tarea1fr2.java similarity index 100% rename from UA2/tareas/dev_0/tarea_1/ua2tarea1fr2.java rename to UA2/tareas/dev_22/tarea_1/ua2tarea1fr2.java diff --git a/UA2/tareas/dev_0/tarea_2/ua2tarea2.java b/UA2/tareas/dev_22/tarea_2/ua2tarea2.java similarity index 100% rename from UA2/tareas/dev_0/tarea_2/ua2tarea2.java rename to UA2/tareas/dev_22/tarea_2/ua2tarea2.java diff --git a/UA2/tareas/dev_0/tarea_3/ua2tarea3.java b/UA2/tareas/dev_22/tarea_3/ua2tarea3.java similarity index 100% rename from UA2/tareas/dev_0/tarea_3/ua2tarea3.java rename to UA2/tareas/dev_22/tarea_3/ua2tarea3.java diff --git a/UA4/tareas/dev_0/tarea_2/2_dam_psp_ua4_tarea_2.postman_collection.json b/UA4/tareas/dev_22/tarea_2/2_dam_psp_ua4_tarea_2.postman_collection.json similarity index 100% rename from UA4/tareas/dev_0/tarea_2/2_dam_psp_ua4_tarea_2.postman_collection.json rename to UA4/tareas/dev_22/tarea_2/2_dam_psp_ua4_tarea_2.postman_collection.json diff --git a/UA4/tareas/dev_0/tarea_2/BasicHandler.java b/UA4/tareas/dev_22/tarea_2/BasicHandler.java similarity index 100% rename from UA4/tareas/dev_0/tarea_2/BasicHandler.java rename to UA4/tareas/dev_22/tarea_2/BasicHandler.java diff --git a/UA4/tareas/dev_0/tarea_2/DataStore.java b/UA4/tareas/dev_22/tarea_2/DataStore.java similarity index 100% rename from UA4/tareas/dev_0/tarea_2/DataStore.java rename to UA4/tareas/dev_22/tarea_2/DataStore.java diff --git a/UA4/tareas/dev_0/tarea_2/Person.java b/UA4/tareas/dev_22/tarea_2/Person.java similarity index 100% rename from UA4/tareas/dev_0/tarea_2/Person.java rename to UA4/tareas/dev_22/tarea_2/Person.java diff --git a/UA4/tareas/dev_0/tarea_2/PersonHandler.java b/UA4/tareas/dev_22/tarea_2/PersonHandler.java similarity index 100% rename from UA4/tareas/dev_0/tarea_2/PersonHandler.java rename to UA4/tareas/dev_22/tarea_2/PersonHandler.java diff --git a/UA4/tareas/dev_0/tarea_2/api.java b/UA4/tareas/dev_22/tarea_2/api.java similarity index 100% rename from UA4/tareas/dev_0/tarea_2/api.java rename to UA4/tareas/dev_22/tarea_2/api.java diff --git a/UA4/tareas/dev_0/tarea_3/conf.ini b/UA4/tareas/dev_22/tarea_3/conf.ini similarity index 100% rename from UA4/tareas/dev_0/tarea_3/conf.ini rename to UA4/tareas/dev_22/tarea_3/conf.ini