1. Universidad Nacional de San Antonio Abad del Cusco
Departamento Académico de Informática
Programación Concurrente y Distribuida
Práctica Nº 3
Semáforos
Ing. Iván Medrano Valencia
1. OBJETIVO.
En la Práctica Nº 2 se pudo comprobar que cómo dos proceso cooperantes sin hacer
ninguna consideración de concurrencia lleva a un comportamiento anómalo. Esto llevó a la
conclusión de que es necesario algún mecanismo de exclusión mutua: mientras un
proceso está accediendo al recurso compartido hay que impedir que otros procesos
puedan acceder al mismo. El objetivo de esta práctica es lograr la exclusión mutua
utilizando el mecanismo semáforo.
2. BASE TEORICA COMPLEMENTARIA
Semáforo.
Es una de las primeras herramientas utilizadas para proteger la sección crítica y lograr la
exclusión mutua, además sirve para diseñar protocolos de sincronización entre procesos.
Consta de dos operaciones primitivas: P y V
V señala la ocurrencia de un evento (signal)
P se usa para demorar un proceso hasta que ocurra un evento (wait)
P(s): mientras s > 0 s := s - 1
V(s): s := s + 1
Los semáforos pueden estar disponibles en un lenguaje de programación, como
construcción del lenguaje, o como servicio del sistema operativo invocado mediante
llamadas al sistema. Cuando son proporcionados por el sistema operativo, las variables
semáforo no son declaradas ni manipuladas en el lenguaje, sino que se manipulan a través
de llamadas al sistema tales como CREAR_SEMAFORO, ASOCIAR _A_SEMAFORO,
ESPERA, SEÑAL, CERRAR_SEMAFORO.
En la presente práctica utilizaremos el lenguaje JAVA para implementar semáforos.
Implementación.
class Semaforo
{ protected long a_permisos;
public Semaforo()
{
a_permisos=0;
}
public Semaforo(long p_permisos)
{
a_permisos=p_permisos;
}
public synchronized void V()
{
++a_permisos;
2. Programación Concurrente y Distribuida Semáforos
2
notify();
}
public void P() throws InterruptedException
{
if(Thread.interrupted()) throw new InterruptedException();
synchronized (this)
{
try
{
while (a_permisos <=0)
wait();
--a_permisos;
}
catch (InterruptedException ie)
{
notifyAll();
throw ie;
}
}
}
}
Aquí es necesario aclarar algunos conceptos.
La palabra clave synchronized permite la sincronización de métodos. Una declaración:
synchronized void f()
{
/* cuerpo del método */
}
es equivalente a:
void f()
{
synchronized (this)
{
/* cuerpo del método */
}
}
3. DESARROLLO DE LA PRACTICA.
EJEMPLO 1
Seguiremos tomando como problema a resolver el de la Práctica Nº 2.
Paso 1.- Compilar y ejecutar los siguientes programas.
public class Movimiento extends Thread
{ float a_monto;
CuentaBanco a_cta;
Semaforo a_mutex;
int a_tiempo;
public Movimiento(CuentaBanco p_cta, float p_monto, int p_tiempo,
Semaforo p_mutex)
{
a_cta=p_cta;
a_monto=p_monto;
a_tiempo=p_tiempo;
a_mutex=p_mutex;
}
3. Programación Concurrente y Distribuida Semáforos
3
public void run()
{
try
{
a_mutex.P(); //--protege la sección crítica
//--INICIO SECCION CRITICA
float saldo= a_cta.obtenerSaldo();//---obtiene saldo anterior
sleep(a_tiempo); //--la cajera cuenta el dinero
saldo=saldo+a_monto; //--obtiene nuevo saldo
a_cta.actualizarSaldo(saldo);
//-- FIN SECCION CRITICA
a_mutex.V(); //--libera la sección crítica
}
catch(InterruptedException e)
{
}
}
}
//--aplicación
class AppBanco
{
public static void main(String[] arg)
{ Semaforo mutex = new Semaforo(1);
CuentaBanco cuenta= new CuentaBanco();
Movimiento abono = new Movimiento(cuenta, 500,400, mutex);
Movimiento cargo = new Movimiento(cuenta, -300,300,mutex);
abono.start();
cargo.start();
try
{
abono.join();
cargo.join();
}
catch(InterruptedException e)
{
}
System.out.println("Saldo Final= "+cuenta.obtenerSaldo());
}
}
Pregunta 1.- Es ahora correcta la ejecución del programa, explique por qué?.
Pregunta 2.- Cree varios hilos que abonan y varios que retiran dinero de la cuenta y
verifique si hay consistencia en los datos.
TRABAJO:
Suponer que estamos en una discoteca y resulta que está estropeado el servicio de
chicas y todos tienen que compartir el de chicos. Se pretende establecer un protocolo de
entrada al servicio usando semáforos en el que se cumplan las siguientes restricciones:
- chicas sólo puede haber una a la vez en el servicio
- chicos puede haber más de uno, pero con un máximo de cinco
- los chicos tienen preferencia sobre las chicas. Esto quiere decir que si una chica
está esperando y llega un chico éste puede pasar. Incluso si no puede entrar en el
servicio porque hay ya 5 chicos pasará antes que la chica cuando salga algún chico.
4. Programación Concurrente y Distribuida Semáforos
4
4. BIBLIOGRAFÍA.
Doug Lea “Programación Concurrente en Java” 2da. Edición.
Addison Wesley 2001.
Deitel y Deitel “JAVA How to Program” 3ra. Edición Prentice Hall
1999.
Ken Arnold “El Lenguaje de Programación JAVA”. 3ra. Edición.
James Goslin Addison Wesley 2001
David Holmes
Milenkovic “Sistemas Operativos– Conceptos y Diseño” 2da. Edición.
McGraw Hill 1994.
http://www.oup-usa.org/docs Oxford University Press
http://java.sun.com/ Sun MycroSystems.
Cusco, noviembre de 2017