Está en la página 1de 3
Problema (6 puntos) Supongamos un escenario en el que un proceso (P1) consulta la temperatura de la habitacién a través de un termémetro conectado por USB y le debe hacer llegar cada dato leido a otro proceso (P2) para que los procese. 1) Indique el mecanismo de comunicacién que considere mas adecuado para los siguientes casos y justifique si presenta o no problemas de sincronizacién: ) (0,5 puntos] P1 y P2 son procesos locales emparentados b) [0,5 puntos] P1 y P2 son procesos locales no emparentados ©) [0,5 puntos] P1 y P2 son procesos ligeros 4) [0,5 puntos] P1 y P2 son procesos en maquinas distintas 2) [2 puntos] Complete el siguiente cédigo para solucionar el problema propuesto usando procesos ligeros, ‘comunicacién a través de un buffer circular en la regidn de datos capaz de almacenar 10 valores de temperatura y resolviendo la sincronizacion mediante mutex/condicién. Indique qué cédigo es necesario afiadir en cada una de las etiquetas: A, B,C, Dy E. /1 Cédigo A // void Pl(void) { int i = 8, temp; while(1) { temp = Leer Temperatura USB( ); 11 C6digo B // int + a void P2(void) { int i = 0, temp; while(1) { 11 C6digo C // ins Procesar_Temperatura(temp) ; t + int main(void) { pthread_t thP1, thp2; 11 Codigo D // pthread_create(&thP1, NULL, (void*) P1, NULL); pthread_create(&thP2, NULL, (void*) P2, NULL); pthread_join(thP1, NULL); pthread join(thP2, NULL); 11 Cédigo E // return 0; } 3) [2 puntos] Supongamos ahora que hubiera varios procesos pesados del tipo P2 que se ejecutaran en la misma maquina y que tuvieran que guardar en un fichero comin (llamado “TEMPERATURAS') las veces que se ha producido una determinada temperatura (leer la cuenta actual del fichero, sumar 1 y escribir la nueva cuenta) Indique qué problemas de sincronizacién existirian, qué solucin se podria usar y esboce el cédigo necesario para la sincronizacién. Nota: Sin necesidad de implementarlas, se puede hacer uso de las funciones int temperatura_a_num_registro(int temperatura), que nos diré en qué nimero de registro del fichero se almacena la cuenta de una temperatura, y la funcién int recibir_temperatura(void), que recibe el dato de la temperatura de un proceso P1 SOLUCION Antes de pasar a tratar cada apartado cabe seiialar que el problema propuesto encaja perfectamente en el modelo clisico de productor-consumidor. En este caso PI ejerceria la labor de proceso productor y P2 el rol de proceso consumidor 1) En el enunciado se pide tnicamente el mecanismo de comunicacién més adecuado, pero en esta solucién se discuten todas las opciones posibles. a) Procesos emparentados. Se pueden contemplar las siguientes opcione PIPE: ambos procesos se podrian comunicar usando un PIPE y ademas eso garantizaria la sincroniza- in entre ellos de forma natural, El proceso P1 escribiria la temperatura en un extremo del PIPE y el proceso P2 leerfa el dato desde el otro extremo. Esta misma solucién se podria aplicar usando un FIFO, aunque al ser procesos emparentados un PIPE seria més natural. ii, Regién de memoria compartida (por ejemplo, creada con un mmap, con la opcian MAP_SHARED y MAP_ANONYMOUS). En este escenario se usaria un buffer circular en la regién de memoria com- partida para que P1 fuera almacenando las temperaturas leidas y que las fuera leyendo el proceso P2. En este caso tendriamos problemas de sincronizacién. Por un lado, P1 necesitaria saber si P2 ha leido uun dato antes de sobreseribirlo; y por otro, P2 necesitaria saber si un dato ha sido ya escrito por PI antes de leerlo. Fichero: se podria usar un fichero para almacenar un buffer circular, aunque esta solucién tendria un rendimiento muchisimo menor que en caso de la regién de memoria compartida. En este caso tendria- ‘mos el mismo problema de sincronizacién que en el caso de usar una regién de memoria compartida iv. Sockets: finalmente, también se podria considerar utilizar sockets orientados a conexién local (UNIX) de manera similar a lo comentado para los pipes. ») Procesos no emparentados. Se podrian contemplar las siguientes opciones: i. FIFO: el esquema seria el mismo que el del uso de un PIPE en procesos emparentados y no presenta- ria problemas de sincronizacién Regién de memoria compartida. Al no ser emparentados, se podria realizar mediante la proyeceién compartida de un fichero. Los problemas de sincronizacién serian los mismos que en el caso de a.ii. iii, Fichero: seria idéntico a lo expuesto en el caso a.iii iv. Sockets: idem que para el caso a.iv ©) Procesos ligeros. Se podrian contemplar las siguientes opciones: i. Se podria usar alguna de las regiones de memoria que comparten los procesos ligeros, como por ejemplo el HEAP (previa reserva de espacio) 0 la regién de datos (usando variables globales), para almacenar un buffer circular. Los problemas de sincronizacién serian equivalentes a los expuestos a.i Fichero, tuberias y sockets: seria menos aconsejables que en la opcién anterior porque la sobrecarga que introducen seria mayor. 4) Procesos remotos. Al ser procesos remotos se deben comunicar mediante paso de mensajes usando so- ckets del dominio AF_INET y tipo stream (para no perder ningin dato y recibirlos de forma ordenada). Este en- foque no presenta ningin problema de sineronizacién ya que el propio mecanismo del socket lo da resuelto. 2) 11 céaigo 2/1 feline SIZE 10 Ant butter (SIZE) ; Ant datosDisponible: Lomutex_t mite (Ceond_§ no_ileno, no_vacto = 0; pene 1d mutex lock (dmutex) pthread putes unlock (ématex) * 11 codigo © 1 pthread mutex lock (eeutex) (atosDisponibles == 0) ‘pthread cond vait(éno_vacio, mutex) vemp = Duffer[i + Size): 1 eond_signal (éne_ileno) J mutex_unlock (amutex) | 11 ceaigo D1 pthread mutex _init (cmutex, NULL) ; (cond init (éne_tieno, NULL) {Ceond_inst(ene_vacio, NULL) U1 ceaigo © // pthread cond destroy (sno_11eno) ; pthread cond destroy (sne_vacie) ; pthread puter destroy (imitex) : 3) Como los procesos P2 tienen que leer un dato del fichero, modificarlo y escribirlo, podria darse una condi- cién de carrera si mas de uno de estos procesos intentara leer y actualizar la cuenta de una temperatura, resul- tando en una cuenta incorrecta, Se trata de un problema donde solo hay involucrados escritores. Este problema se podria solucionar usando cerrojos sobre ficheros de tipo exclusivo de forma que, antes de leer y actualizar la cuenta de una determinada temperatura, se podria establecer el cerrojo sobre el registro especifico dentro del fichero para esa temperatura, y asegurar asi exclusién mutua, Los valores son datos de tipo entero que basta almacenarlos en el fichero en la posicién asociada al correspondiente registro, que se obtiene invocando la funciones auxiliares indicadas en el enunciado, El cédigo podria ser el siguiente: int pos, cuenta; £1.1_whence = SEEK_SET; £1.10len = sizeof (int) ; £11 pid = getpid() ; £4 = open ("TEMPERATURAS", _RDWR) ; while (1) { pos = temperatura_a_num_registro(recibir_temperatura( )) * sizeof (int) ; £1.1_start = pos; f£1.1_type = F_WRLCK; fontl (fd, F_SBTLKW, £1); lseek(fd, pos, SEEK SET) ; read(fd, gcuenta, sizeof (int); cuentat+; lseek(fd, pos, SEEK_SET); write(fd, cuenta, Sizeof(int)) ; £1.1_type = F_UNLCK; fentl (fd, F_SBTLK, &£1);

También podría gustarte