pan.cpp. El ejecutable que
resulte de la compilación de dicho programa por Visual C++
admitirá un único parámetro obligatorio en la línea de órdenes.
Dicho parámetro especifica la velocidad de la simulación y
será el valor que se pase a la función inicio de
la biblioteca de enlace dinámico pansal.dll que
se describe más abajo.
pansal.dll y vendrá acompañada por un fichero
de cabeceras pansal.h donde se especifica el
prototipo de las funciones exportadas (en realidad un puntero
al tipo de dichas funciones) y la definición de
algunas macros para hacer el manejo de las funciones más
sencillo. La DLL exportará las siguientes dos funciones
que debéis usar en la práctica:
void inicio(struct datos_panaderIa **sdpp, LONG intervalo)Esta función debe ser llamada al principio del programa, después de haber cargado la biblioteca. Se encarga de dar valor inicial a estructuras internas y de dibujar la pantalla inicial. En el parámetro
intervalo se ha
de pasar el intervalo de tiempo, en ms, que
transcurre entre movimientos de la animación
de pantalla. Cuanto menor sea este número,
más rápida irá la simulación. En cuanto a
sdpp, sirve para que la función
nos devuelva un puntero a una estructura del
tipo struct datos_panaderIa. Esta
estructura, como se puede observar en el
fichero de cabeceras pansal.h,
consta de los siguietes campos:
LONG num_panel:
aquí se llevará cuenta
del número que aparece en el panel
del marcador de turnos.
LONG num_ticket:
este campo indica el
número del próximo ticket disponible
en el dispensador de tickets de turno.
LONG caja:
indica cuánto dinero hay en
la caja.
BOOL parar: este campo,
inicialmente
igual a false pasará a
true cuando la simulación
deba parar, posiblemente debido a un
error en la sincronización o en la
secuencia de acciones que realizan los
hilos.
void accion(int personaje,int proceso,char *complementos)Es la función núcleo de la DLL. Cada personaje del problema debe invocar esta función cada vez que vaya a realizar una acción para que esta se vea reflejada en la presentación por pantalla. El argumento
personaje puede ser
PANADERO, DEPENDIENTE1,
DEPENDIENTE2, CLIENTE1,
CLIENTE2 o CLIENTE3.
Cada personaje realizará una serie de
procesos en orden, que describimos
a continuación:PANADERO realizará continuamente:
AMASAR
IR_HORNO
HORNEAR
IR_CESTO
DEJAR_PAN: sólo se puede
invocar correctamente esta función si el
cesto de pan no está lleno.
IR_MESA
DEPENDIENTE1 y DEPENDIENTE2
ejecutan un bucle continuo de los siguientes procesos:
IR_PULSADOR
PULSAR: el hilo del dependiente
ha incrementado el campo num_panel
de la estructura
struct datos_panaderIa. Toma
los dos últimos dígitos del
valor del panel después de pulsar, y se los
que pasa como
complementos en este proceso.
IR_MOSTRADOR: se pasa como
complementos el mismo valor que
en PULSAR.
IR_CESTO
COGER_PAN: debe haber al menos un
pan en el cesto para poder cogerlo.
VOLVER_MOSTRADOR
DAR_PAN: el cliente debe estar
todavía en el mostrador para darle el pan.
IR_CAJA: el cliente debe haberle
pagado para poder ir a la caja.
GUARDAR_DINERO: el hilo que invoca
este proceso debe haber incrementado previamente
el campo caja de la estructura
struct datos_panaderIa.
COGER_NUMERO: el hilo cliente que
invoca la función ha cogido previamente e
incrementado el valor del campo
num_ticket de la estructura
struct datos_panaderIa.
Las dos últimas cifras del valor obtenido
antes de incrementarlo se pasarán en la variable
complementos.
IR_DEPENDIENTE1 ó
IR_DEPENDIENTE2: si el hilo decide
que debe acudir al mostrador de uno de los
dependientes, invocará esta función. Le
pasará en la variable complementos
lo mismo que pasó cuando llamó a
COGER_NUMERO.
PEDIR_PAN1 ó
PEDIR_PAN2: cuando el hilo sepa
que el dependiente ha llegado al mostrador, le
pedirá pan.
PAGAR1 ó PAGAR2:
cuando el dependiente le haya dado el pan al
cliente, el cliente llamará a uno de estos
procesos para pagar. El dependiente debe esperar
hasta que el cliente le pague.
VOLVER_DE1 ó
VOLVER_DE2: el cliente vuelve a su
sitio. Se invoca uno u otro proceso dependiendo,
como en los casos anteriores, de qué
dependiente le haya atendido.
COMER_PAN
pan.cpp.
Primero tenéis que cargar la bilbioteca de enlazado dinámico
pansal.dll. Cuidad de comprobar el valor
devuelto por LoadLibrary para ver que no ha
habido problemas. Si todo va bien, la pantalla se
limpiará y aparecerá durante dos segundos el mensaje:
Biblioteca de enlazado dinámico pansal.dll © 2002 Guillermo González Talaván. Universidad de Salamanca
inicio.
Cuidado con el paso por referencia del puntero
a la estructura struct datos_panaderIa.
De nuevo, comprobad que no falla la función de la
API GetProcAddress. Llamad a la función
obtenida y comprobad que en la pantalla aparece
el estado inicial del sistema.
inicio sea el introducido en la
línea de órdenes. Para ir probando la práctica, usad
un intervalo largo (500 ms, por ejemplo) e idlo
disminuyendo según progreséis.
accion y probarla haciendo que el
panadero amase y vaya al horno.