Está en la página 1de 28

Integrantes del Grupo 17:

‐ TANIA PACHUCA SOLARES


‐ VENTURA MEZA MARTÍNEZ

Nombre del docente:

‐ MTRO. SERGIO GONZALEZ OLIVA.

Fecha de entrega: 21 de agosto de 2023.


UNIDAD 3: PROYECTO INTEGRADOR ETAPA I.

1. Con base en el material consultado en la unidad resuelve los ejercicios que se plantean
acerca de los siguientes temas:

 Procesos en los sistemas operativos


 Concurrencia
 Hilos
 Región crítica
 Semáforos

Parte I
1. Descarga e instala el compilador de Java, a partir de la versión 7.
2. Descarga e instala algún IDE de desarrollo para Java de tu elección, para compilar y
correr programas.
3. Realiza la compilación y corrida del programa Tuberia.java.
4. Describe el código, haciendo énfasis en las partes en las que se realiza la concurrencia
y cómo se maneja.
5. Utiliza las librerías semaphore.h y pthread.h. Ubícalas en el lugar de las librerías
dentro del Sistema Operativo Linux.
6. Revisa el código programa.c. Describe el código y realiza al menos 2 corridas del
programa.
7. Elabora un breve informe de los resultados, archivos y problemáticas que se
desarrollan al correrlo.

Parte II
8. Elabora un programa en Java basándote en el programa Tuberia.java, para modelar
el “Problema del barbero dormilón”, que se describe a continuación, utilizando
HILOS, como en el programa de la tubería:
 Identifica la región crítica, los hilos, la concurrencia, etc.
 Considera los resultados de la solución implementada, si cumple con los
criterios expresados y cómo se evitan fallos

Problema del Barbero dormilón


En una barbería trabaja un barbero
que tiene un único sillón y varias
sillas para esperar. Cuando no hay
clientes, el barbero se sienta en una
silla y se duerme.
Cuando llega un nuevo cliente, éste,
o bien despierta al barbero o — si el
barbero está afeitando a otro
cliente— se sienta en una silla (o se
va si todas las sillas están ocupadas
por clientes esperando). El problema
consiste en realizar la actividad del
barbero sin que ocurran condiciones
de carrera.

9. Redacta tu informe de resultados (Parte I y II) considerando lo siguiente:


 Código desarrollado en Lenguaje C
 Imágenes con resultados de la ejecución
 Explicación completa de la implementación haciendo énfasis en la parte de los
procesos, su creación, gestión y concurrencia.

10. Redacta una conclusión sobre la comunicación entre procesos, utilizando semáforos,
su utilidad y los problemas que crees que se puedan resolver utilizando esta técnica.

11. Agrega las fuentes consultadas (mínimo 2) referenciadas en estilo APA.

12. Al finalizar, vuelve a la plataforma y sigue los pasos que se indican para enviar tu
actividad.
DESARROLLO PARTE 1:
1.- Instalamos Ubuntu en Windows 11.
Instalamos Java 11, a través del comando sudo apt install openjdk-11-jdk, en la
terminal de Ubuntu.
2.- Instalamos el IDE NetBeams.
3.- Realizamos la compilación del código sin que corriera exitosamente.
4.- El código lo que realiza es asigna un hilo al productor y uno al consumidor. Las
reglas para evitar problemas las configuramos de tal manera que cuando el
almacén (Buffer) esta lleno el productor deja de producir y cuando el almacén esta
vacío el consumidor deja de consumir.
5.- La librería Semaphore.h en Linux está en: Equipo/usr/src/linux-hwe-6.2.0-
26/include/linux y pthread.h en Equipo/usr/share/man/man7.
6.- Se revisa el código, donde la parte clave en los hilos, esta al monitorear el
estado del buffer, e indicando al consumidor que pare cuando el buffer este vacío
y al productor que pare cuando el buffer esta lleno.
Se modifica el código y funcionó correctamente:

CODIGO FUENTE:
CLASE BUFFER:
package com.mycompany.a3_eq17;

import java.util.logging.Level;
import java.util.logging.Logger;

public class Buffer {

private char[] buffer;


private int siguiente;
private boolean estaVacia;
private boolean estaLlena;

public Buffer(int tamanio){


this.buffer = new char[tamanio];
this.siguiente = 0;
this.estaVacia = true;
this.estaLlena = false;
}
public synchronized char consumir(){
while(this.estaVacia){
try {
wait();
} catch (InterruptedException ex) {
Logger.getLogger(Buffer.class.getName()).log(Level.SEVERE, null,
ex);
}
}

siguiente--;
this.estaLlena = false;
if(siguiente == 0){
this.estaVacia = true;
}

notifyAll();

return this.buffer[this.siguiente];
}

public synchronized void producir(char c){


while(this.estaLlena){
try {
wait();
} catch (InterruptedException ex) {
Logger.getLogger(Buffer.class.getName()).log(Level.SEVERE, null,
ex);
}
}

buffer[siguiente] = c;
siguiente++;
this.estaVacia = false;
if(siguiente == this.buffer.length){
this.estaLlena = true;
}

notifyAll();
}

CLASE PRODUCTOR:

package com.mycompany.a3_eq17;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Productor extends Thread {

private Buffer buffer;


private final String letras = "abcdefghijklmnopqrstuvxyz";

public Productor(Buffer b){


this.buffer = b;
}

public void run(){


while(true){
try {
char c = letras.charAt((int) (Math.random() * letras.length()));
buffer.producir(c);
System.out.println("Depositado el caracter " + c + " del buffer");

sleep((int) (Math.random() * 4000));


} catch (InterruptedException ex) {
Logger.getLogger(Productor.class.getName()).log(Level.SEVERE,
null, ex);
}
}
}

CLASE COMSUMIDOR:
package com.mycompany.a3_eq17.

import static java.lang.Thread.sleep;


import java.util.logging.Level;
import java.util.logging.Logger;

public class Consumidor extends Thread {

private Buffer buffer;

public Consumidor(Buffer b) {
this.buffer = b;
}

public void run() {


while (true) {
try {
char c = this.buffer.consumir();
System.out.println("Recogido el caracter " + c + " del buffer");

sleep((int) (Math.random() * 4000));


} catch (InterruptedException ex) {
Logger.getLogger(Consumidor.class.getName()).log(Level.SEVERE,
null, ex);
}
}
}

CLASE PRINCIPAL A3_EQ7;

package com.mycompany.a3_eq17;

public class A#_EQ17 {

public static void main(String[] args) {


Buffer b = new Buffer(10);
Productor p = new Productor(b);
Consumidor c = new Consumidor(b);

p.start();
c.start();
}
}

Evidencia:
7.- Debido a nuestra falta de conocimiento en ambiente Linux y programación en
java, fue bastante complejo para nosotros y entretenido a la vez, al final de
cuentas con varios tutoriales, pudimos lograrlo.
PARTE 2:
Se adjunta Código Fuente y evidencia de la programación:
CONCLUSION:
La utilización de los semáforos nos permitirá ejecutar varios hilos de manera
ordenada, para que de esta forma, se puedan ejecutar en un orden, sin un semáforo,
pueden venir problemas de concurrencia o de carrera. Estos problemas se
solucionan con los semáforos, las funciones wait() y sleep(), como lo realizamos en
la parte 1 de esta actividad.
Referencias:

 Gelpi, D. (2013). Sistemas operativos monocompuesto [Versión electrónica].


Recuperado de https://elibro.net/es/ereader/uvm/43258

 Wolf, G., Ruiz, E., Bergero, F. y Meza, E. (2015). Fundamentos de Sistemas


Operativos Haga clic para ver más opciones [Versión electrónica].
Recuperado de http://ru.iiec.unam.mx/2718/1/sistemas_operativos.pdf

 Henrik, H. (2016). Synchronization Mechanisms Haga clic para ver más


opciones [Versión electrónica]. Recuperado de
http://www2.compute.dtu.dk/courses/02158/sync.pdf

 Cortés, E. D. (2022, 21 febrero). El Camino Del Backend Developer: Hilos y


Concurrencia. La Sombra de Dijkstra.
https://www.programando.org/blog/2021/02/20/elcamino-del-backend-
developer-hilos-y-concurrencia/

 UC3M. (s. f.). Capítulo 11. Los hilos.


https://www.it.uc3m.es/pbasanta/asng/course_notes/threads_es.html
UNIDAD 4: PROYECTO INTEGRADOR ETAPA II.
Introducción:
En esta segunda etapa del proyecto integrador aplicaremos las bases de
programación para la construcción de algoritmos que se refieren al manejo de la
concurrencia.

II. Interbloqueos
2.1 Aplicación de los principios de interbloqueo
• Desarrolla los ejercicios en los que apliques los principios del interbloqueo. Para
ello realiza lo siguiente:

Desarrollo de la actividad:

a) Realiza un programa que maneje una lista de contactosde agenda que


incluya nombre, e-mail y teléfono.

1. for (i = 0; i < cont; i++) {


2. if (strcmpi(busca, control[i].nom) == 0) {
3. printf("\nNombre: %s\n", control[i].nom);
4. printf("Tel\202fono fijo: %d\n", control[i].t_f);
5. printf("Tel\202fono m\242vil: %d\n", control[i].t_m);
6. printf("Direcci\242n: %s\n", control[i].dir);
7. printf("E-mail: %s\n", control[i].email);
8. printf("Grupo: %s\n", control[i].grupos);9. }
10. }
11. }
12. void contactos() {
13. int aux, i, j;
14. char auxc[50];
15. system("cls");
16. for (i = 0; i < cont - 1; i++) {
17. for (j = 0; j < cont - 1 - i; j++) {
18. if (strcmp(control[j].nom, control[j + 1].nom) > 0) {
19. strcpy(auxc, control[j].nom);
20. strcpy(control[j].nom, control[j + 1].nom);
21. strcpy(control[j + 1].nom, auxc);
22. aux = control[j].t_f;
23. control[j].t_f = control[j + 1].t_f;
24. control[j + 1].t_f = aux;
25. aux = control[j].t_m;
26. control[j].t_m = control[j + 1].t_m;
27. control[j + 1].t_m = aux;
28. strcpy(auxc, control[j].dir);
29. strcpy(control[j].dir, control[j + 1].dir);
30. strcpy(control[j + 1].dir, auxc);
31. strcpy(auxc, control[j].email);
32. strcpy(control[j].email, control[j + 1].email);
33. strcpy(control[j + 1].email, auxc);
34. strcpy(auxc, control[j].grupos);
35. strcpy(control[j].grupos, control[j + 1].grupos);
36. strcpy(control[j + 1].grupos, auxc);
37. }
38. }
39. }
40. printf("\nAgenda.\n");
41. for (i = 0; i < cont; i++) {
42. printf("\n%d.Nombre: %s\n", (i + 1), control[i].nom);
43. printf("Tel\202fono fijo: %d\n", control[i].t_f);
44. printf("Tel\202fono m\242vil: %d\n", control[i].t_m);
45. printf("Direcci\242n: %s\n", control[i].dir);
46. printf("E-mail: %s\n", control[i].email);
47. printf("Grupo: %s\n", control[i].grupos);
48. }
49. }

b) Revisa los ejemplos de interbloqueo 1/2 y 2/2 (Diapositivas − Páginas


31 y 32) que aparecen en el documento Capítulo 7. Interbloqueos.

1. //Versión con posible interbloqueo


2. struct nodo {
3. struct nodo* siguiente;
4. /* otros campos */
5. 5. };
6. struct lista {
7. pthread_mutex_t mutex_lista;
8. struct nodo* primer_nodo; 9. };
9. void mover_elemento_de_lista(struct lista* origen, struct lista* destino,
10. struct nodo* elemento, int posicion_destino) {
11. pthread_mutex_lock(&origen->mutex_lista);
12. pthread_mutex_lock(&destino->mutex_lista);
13. /* mueve el elemento a ls lista destino */
14. pthread_mutex_unlock(&origen->mutex_lista);
15. pthread_mutex_unlock(&destino->mutex_list);
16. 17. }
17. //Versión libre de interbloqueos
18. void mover_elemento_de_lista(struct lista* origen, struct lista* destino,
19. struct nodo* elemento, int posicion_destino) {
20. if (origen < destino) {
21. pthread_mutex_lock(&origen->mutex_lista);
22. pthread_mutex_lock(&destino->mutex_lista);
23. 24. }
24. else {
25. pthread_mutex_lock(&destino->mutex_lista);
26. pthread_mutex_lock(&origen->mutex_lista);
27. 28. }
28. /* mueve el elemento a ls lista destino */
29. pthread_mutex_unlock(&origen->mutex_lista);
30. pthread_mutex_unlock(&destino->mutex_lista);
31. }

c) Con base en el ejemplo anterior realiza la modificación de la lista de


contactos, evitando los bloqueos que supone la primera diapositiva.
d) Modifica el código adjunto para realizar esta tarea a través del patrón de
diseño singleton y además el uso de threads en java.
e) Escribe un programa de tal forma que se resuelva el problema de los
interbloqueos utilizando algún recurso para poder generar el método denominado
usar ambos recursos(). Puede ser una estructura, una matriz, un arreglo, etc.

#include <iostream>
using std::cout;
using std::cin;
using std::endl;
#include <cstring>
using std::string;
#include <cstdlib> // system(" ") limpiar
void menu();
void Ingresar(struct Datos Persona[],int,int);
void Mostrar(struct Datos Persona[],int);
void ImprFicha(struct Datos Persona[],int,int);
void Buscar(struct Datos Persona[],int);
void BuscaFicha(struct Datos Persona[],int);
void BuscaNombre(struct Datos Persona[],int);
void BuscaTel(struct Datos Persona[],int);
void Modificar(struct Datos Persona[],int);
void Eliminar(struct Datos Persona[], int& numero, int TAM);

struct Cumpleanos
{
string Nacimiento;
};
struct Datos
{
string Nombre;
string Direccion;
string Telefono;
Cumpleanos Fecha;
};

int main()
{
const int LEN = 2;
Datos Persona[LEN];
int index = 0;
int opcion;
bool salir;

do
{
menu();
cout << "\n\t Elija la opcion: ";
cin >> opcion;
cin.ignore();
switch (opcion)
{
case 1:
system(" ");
Ingresar(Persona,index,LEN);
index++;
break;
case 2:
system(" ");
Mostrar(Persona,index);
break;
case 3:
system(" ");
Buscar(Persona,index);
break;
case 4:
system(" ");
Modificar(Persona,index);
break;
case 5:
system(" ");
Eliminar(Persona, index, LEN);
break;
case 6:
salir = true;
break;
default:
system(" ");
cout << "Ingrese Opcion valida\n\n";
break;
}
}while(salir == false);
return 0;
}

void menu()
{
cout << "\t AGENDA \n\n";
cout << "\t 1. Ingresar." << endl;
cout << "\t 2. Mostrar Registros." << endl;
cout << "\t 3. Buscar contacto." << endl;
cout << "\t 4. Modificar." << endl;
cout << "\t 5. Eliminar." << endl;
cout << "\t 6. SALIR." << endl;
}

void Ingresar(struct Datos Persona[], int numero, int TAM)


{
if(numero < TAM)
{
cout << "\t Igresar Registro : #" << numero << endl << endl;
cout << " Nombre: ";
getline(cin,Persona[numero].Nombre);
cout << " E-mal Id usuario@servidor.dominio.pais: ";
getline(cin,Persona[numero].Direccion);
cout << " Telefono Movil: ";
getline(cin,Persona[numero].Telefono);
cout << " Fecha de nacimiento): ";
getline(cin, Persona[numero].Fecha.Nacimiento);
cout << endl << endl;
}
else
cout << "ALMACENAMIENTO FUERA DE LIMITE DE SISTEMA " <<
endl << endl;
}

void ImprFicha(struct Datos Persona[], int x)


{
cout << "\t Informacion Registro: #" << x << endl << endl;
cout << " Nombre: " << Persona[x].Nombre << endl;
cout << " E-mal Id usuario@servidor.dominio.pais: " <<
Persona[x].Direccion << endl;
cout << " Telefono Movil: " << Persona[x].Telefono << endl;
cout << " Fecha de nacimiento: " << Persona[x].Fecha.Nacimiento;
cout << endl << endl;
}

void Mostrar(struct Datos Persona[], int numero)


{
for(int i=0 ; i<numero ; i++)
{
ImprFicha(Persona,i);
}
cin.get();
system(" ");
}

void Buscar(struct Datos Persona[], int numero)


{
bool exit;
do
{
cout << "\t BUSQUEDA: \n\n";
cout << " 1. # Registro" << endl;
cout << " 2. Nombre" << endl;
cout << " 3. Telefono Movil" << endl;
cout << " 4. SALIR" << endl << endl;

unsigned int op;


cout << " Indique Opcion: ";
cin >> op;
cin.ignore();
cout << endl;
switch(op)
{
case 1:
system(" ");
BuscaFicha(Persona,numero);
break;
case 2:
system(" ");
BuscaNombre(Persona,numero);
break;
case 3:
system(" ");
BuscaTel(Persona,numero);
break;
case 4:
exit = true;
break;
default:
cout << "ERROR, DIGITE OPCION CORRECTA\n";
break;
}
}while(exit == false);
system(" ");
}

void BuscaFicha(struct Datos Persona[], int numero)


{
cout << "\t Busqueda por Registro: \n\n";
unsigned int Ficha;
cout << " Digite # Registro: ";
cin >> Ficha;
cin.ignore();
cout << endl;
for(int i=0 ; i<numero ; i++)
{
if(Ficha == i)
{
ImprFicha(Persona,i);
}
}
cin.get();
system(" ");
}

void BuscaNombre(struct Datos Persona[], int numero)


{
cout << "\t Busqueda por nombre: \n\n";
string nomb;
cout << " Digite el nombre: ";
getline(cin,nomb);
cout << endl;
for(int i=0 ; i<numero ; i++)
{
if(nomb == Persona[i].Nombre)
{
ImprFicha(Persona,i);
}
}
cin.get();
system(" ");
}
void BuscaTel(struct Datos Persona[], int numero)
{
cout << "\t Busqueda por Telefono: \n\n";
string tel;
cout << "Digite Telefono Movil: ";
getline(cin,tel);
cout << endl;
for(int i=0 ; i<numero ; i++)
{
if(tel == Persona[i].Telefono)
{
ImprFicha(Persona,i);
}
}
cin.get();
system(" ");
}

void Eliminar(struct Datos Persona[], int& numero, int TAM)


{
string tel;
cout << "Digite Telefono del contacto a eliminar: ";
getline(cin, tel);
cout << endl;
for (int i = 0; i < numero; i++)
{
if (tel == Persona[i].Telefono)
{
for (int j = i; j < numero - 1; j++)
{
Persona[j] = Persona[j + 1];
}
numero--;
cout << "Contacto eliminado exitosamente." << endl << endl;
break;
}
}
cin.get();
system(" ");
}
void Modificar(struct Datos Persona[], int numero)
{
cout << " Editar la informacion: \n\n";

string tel;
cout << "Digite Telefono Movil: ";
getline(cin,tel);
cout << endl;
for(int i=0 ; i<numero ; i++)
{
if(tel == Persona[i].Telefono)
{
ImprFicha(Persona,i);
cout << " Nombre: ";
getline(cin,Persona[i].Nombre);
cout << " E-mal Id usuario@servidor.dominio.pais: ";
getline(cin,Persona[i].Direccion);
cout << " Telefono Movil: ";
getline(cin,Persona[i].Telefono);
cout << " Fecha de nacimiento: ";
getline(cin, Persona[i].Fecha.Nacimiento);
cout << endl << endl;
}
}
}

Resultados
Reflexionando sobre las mejores prácticas para abordar los desafíos planteados por
los interbloqueos en un sistema operativo, especialmente en relación con los
procesos dentro del mismo sistema, se pueden identificar estrategias efectivas.
La prevención del interbloqueo se enfoca en eliminar las cuatro condiciones
necesarias para su aparición. Aunque la exclusión mutua es inevitable para ciertos
recursos, se puede evitar el interbloqueo si un proceso necesita permiso de
escritura. La retención y espera se resuelve solicitando todos los recursos
simultáneamente para iniciar la ejecución. La no apropiación se supera expropiando
los recursos de un proceso que solicita un recurso no asignado. Evitar el círculo
vicioso de espera requiere una ordenación total de los recursos y la solicitud
ordenada de los mismos.
El enfoque de tratamiento del interbloqueo varía. Ignorar el problema es una práctica
riesgosa adoptada por algunos sistemas. Emplear algoritmos que aseguren la
imposibilidad del interbloqueo se presenta en dos formas: prevención y evasión. La
prevención evita las condiciones de Coffman que generan el interbloqueo. La
evasión monitorea los recursos disponibles, posesión y solicitudes para otorgar o
denegar recursos. Detectar el interbloqueo y aplicar técnicas de recuperación es
otro enfoque útil.
La comprensión de estas prácticas y su aplicación puede ayudar a evitar, resolver
o manejar eficazmente los problemas de interbloqueo, garantizando un
funcionamiento más confiable y fluido del sistema operativo y sus procesos.

Conclusiones:
Es crucial diseñar sistemas de manera que la posibilidad de interbloqueo quede
completamente excluida. Existen dos tipos de métodos para prevenir el
interbloqueo: los indirectos y los directos. Los métodos indirectos se enfocan en
evitar que cualquiera de las tres condiciones necesarias para el interbloqueo
(condiciones 1 a 3) se presente. Por otro lado, los métodos directos se centran en
evitar la formación del círculo vicioso de espera (condición 4). A continuación,
exploraremos las técnicas relacionadas con cada una de estas cuatro condiciones.

Referencias:
Castellanos, L. (2014). Sistemas Operativos [Sitio web]. Recuperado de
https://lcsistemasoperativos.files.wordpress.com/2015/02/sistemas−operativos−luis
−castellanos.pdf
Carreto, J., García, F., Miguel de, P. y Pérez, F. (2007). Sistemas operativos: Una
visión aplicada [Archivo PDF]. Recuperado de
http://laurel.datsi.fi.upm.es/_media/docencia/asignaturas/dso/interbloqu
eos−4pp.pdf
Álvarez, C. (2014). Ejemplo de Java Singleton (Patrones y ClassLoaders) [Sitio
web]. Recuperado de https://www.arquitecturajava.com/ejemplo−de−java−
singleton−patrones−classloaders/

También podría gustarte