Вы находитесь на странице: 1из 6

Benemérita Universidad Autónoma de Puebla

Programación distribuida
Practica 1

Alumno: Iván Escalona Pérez


Primavera 2019

Práctica
El objetivo consiste en implementar un sistema que permita vaciar un contenedor.
Este sistema presenta un problema de sección crítica, es importante identificarla y
utilizar el algoritmo de Peterson para la solución. El sistema se compone de dos
brazos robots y un contenedor con piezas, compartido por ambos. Cada brazo tiene
como propósito tomar una determinada cantidad de piezas del contenedor, de
manera que entre los dos brazos robots logren vaciar el contenedor. Los brazos
pueden tomar la misma o diferente cantidad de piezas. En un principio, el
contenedor cuenta con 50 piezas y con las siguientes restricciones:

 Un brazo sólo puede tomar una pieza cada vez que accede al contenedor.
 Para evitar colisiones entre los brazos, el acceso al contenedor debe ser en
exclusión mutua, es decir, los dos brazos no pueden descargar piezas del
contenedor simultáneamente.

Para implementar el sistema se deberán crear tres clases: Contenedor, Brazo y


Sistema. La clase Contenedor representa el recurso compartido por los dos brazos
y es el objeto del proceso de vaciado. El constructor de la clase debe permitir
asignar un identificador único al contenedor y configurar la cantidad de piezas que
contiene inicialmente. Además, debe ofrecer como parte de su interfaz el método
descargarUnaPieza(). Este método deberá decrementar en una unidad la cantidad
de piezas existentes en el contenedor. La clase Brazo implementa una abstracción
del brazo robot. Cada brazo es un proceso en el sistema concurrente, por lo que,
esta clase deberá implementar la interfaz Runnable. El constructor de la clase

1
tendrá tres parámetros de entrada: un identificador único asignado al brazo, el
número de piezas que deben ser tomadas por el brazo durante su actividad y,
finalmente, el contenedor sobre el que debe trabajar. Esta clase únicamente deberá
implementar el método run(), responsable de tomar del contenedor compartido el
número de piezas indicado. Finalmente, la clase Sistema es la aplicación que
configura y ejecuta el sistema. Contendrá el método main() donde serán
declarados los elementos que constituyen el sistema: un contenedor de 50 piezas
y dos brazos robots que tendrán como propósito vaciarlo. Inicialmente, cada brazo
puede estar configurado para tomar 25 piezas del contenedor, aunque este
parámetro puede ser posteriormente modificado. Para comprobar el
funcionamiento de los brazos cuando tienen que tomar un número diferente de
piezas. ¿Qué podría suceder en este último caso? Un aspecto importante de la
implementación del sistema es poder visualizar y analizar su comportamiento. Con
este propósito, cada vez que un brazo toma una pieza del contenedor deberá
escribir un mensaje que muestre su identificador único e indique el número de
piezas tomadas hasta ese momento.

A continuación, se muestra el comienzo de la ejecución:

Brazo A descarga pieza 1 de 50 del contenedor...


Brazo B descarga pieza 1 de 50 del contenedor...
Brazo A descarga pieza 2 de 50 del contenedor...
Brazo B descarga pieza 2 de 50 del contenedor...
Brazo A descarga pieza 3 de 50 del contenedor...

Datos
Un semáforo es una variable especial (o tipo abstracto de datos) que constituye el
método clásico para restringir o permitir el acceso a recursos compartidos (por
ejemplo, un recurso de almacenamiento del sistema o variables del código fuente)
en un entorno de multiprocesamiento (en el que se ejecutarán varios procesos
concurrentemente).

Los algoritmos de exclusión mutua (comúnmente abreviada como mutex por


mutual exclusion) se usan en programación concurrente para evitar que entre más
de un proceso a la vez en la sección crítica. La sección crítica es el fragmento de
código donde puede modificarse un recurso compartido.

2
La interfaz Runnable debe ser implementada por cualquier clase cuyas instancias
estén destinadas a ser ejecutadas por un hilo. La clase debe definir un método de
no argumentos llamado run.
Esta interfaz está diseñada para proporcionar un protocolo común para los objetos
que desean ejecutar código mientras están activos. Por ejemplo, Runnable es
implementado por la clase Thread. Estar activo simplemente significa que un hilo
se ha iniciado y aún no se ha detenido.

Además, Runnable proporciona los medios para que una clase esté activa sin
subclasificar Thread. Una clase que implementa Runnable puede ejecutarse sin
subclasificar Thread creando una instancia de Thread y pasándose a sí misma
como destino. En la mayoría de los casos, la interfaz de Runnable debe usarse si
solo planea anular el método run () y no otros métodos Thread. Esto es importante
porque las clases no deben clasificarse a menos que el programador intente
modificar o mejorar el comportamiento fundamental de la clase.

Corrida del Programa

3
4
Observaciones
En la corrida del programa ocurrió un detalle que, en el momento de ejecutar el
programa, la reducción del contador descendía solo en números pares como
50,50,48,48,46,46,44,44. Pero en algún momento de la corrida el resultado arroja
un numero non como en este tipo: 8,8,6,6,4,3,2,2. Al investigar un poco más
parece que es un problema usual, el cual tiene que ver con Thread.sleep(espera).
Cuando se le da un tiempo de espera mayor, la corrida comienza a dar más
resultados de números nones.

Conclusión
La implementación del problema de los brazos mecánicos y el contenedor requiere
de utilizar y desarrollar el problema empleando técnicas de exclusión mutua para
permitir la sincronización.

5
6

Вам также может понравиться