Next: Implementación de un controlador Up: Examen de Programación Concurrente Previous: Examen de Programación Concurrente

Subsecciones

- Solución propuesta:

#
Diseño de un controlador para un cruce de trenes [4 puntos]

Se pretende diseñar un controlador que regule las salidas de dos estaciones de tren cuyas vías se cruzan. El aspecto de las estaciones y las vías se muestra a continuacion:

En cada estación se cargan trenes con mercancías y se solicita la salida de un tren cuando está lleno. La forma de solicitar la salida es mediante un terminal de ordenador en que se introduce el número de vía en la que está estacionado el tren y qué tipo de tren es (ver más abajo). Un tren arranca cuando su semáforo se pone en verde. Tras salir de la estación el tren entra en el cruce, en el que no debe haber dos trenes simultáneamente. A la salida del cruce hay un sensor en cada vía que detecta cuándo el tren ya ha abandonado el cruce.

Hay trenes de dos tipos: urgentes y normales. Dentro de cada estación, los trenes urgentes tienen siempre preferencia sobre los normales y la salida de estos últimos debe retrasarse hasta que no haya ningún tren urgente esperando. Dentro de la misma categoría de trenes y en una estación dada las peticiones de salida deben ser atendidas en el mismo orden en que fueron realizadas.

Tenemos el siguiente interfaz para leer datos acerca de los sensores de las vías y de las peticiones de salida de trenes, y para notificar la salida de los trenes:

Se suponen las definiciones de tipos

y se asume que no hay que comprobar la corrección de los datos que llegan del terminal (por ejemplo, nunca se va a decir que hay un tren esperando en una vía cuando en realidad no lo hay) ni preocuparse por eventualidades ajenas al funcionamiento correcto de la estación (por ejemplo, que un tren no pueda arrancar).

Se pide: realizar un diseño para el controlador del cruce que garantice que no habrá choques y que respete las prioridades antedichas entre trenes. Se sugiere seguir los siguientes pasos:

1. Dar el esquema de recursos y procesos. Incluir los nombres de las operaciones en el/los recurso(s) y señalar claramente qué operaciones usa cada proceso.
2. Redactar el código de los procesos que aparezcan en el punto anterior. La comunicación con el personal de la estación y con el sensor del cruce debe utilizar únicamente el interfaz expuesto anteriormente.
3. Especificar formalmente con un C-TAD el/los recurso(s) que aparezcan en el primer apartado de esta pregunta.

Nota: aunque el texto del problema habla únicamente de dos estaciones, pensar en el problema como si tuviese estaciones puede ayudar a tener una solución más elegante.

## Solución propuesta:

Una posible solución se encuentra al principio del ejercicio 2. Otra posible variante, igualmente válida, utiliza únicamente dos clases de procesos: una de ellas inserta en el recurso compartido las peticiones del terminal, y el otro recupera la siguiente petición a ser satifecha y espera a que pase por el cruce:

Esta solución también simplifica el recurso compartido, pues Estacion.PermisoSalirEst no tiene que tener en cuenta la ocupación del cruce. La solución se basa fuertemente en la cadencia y no cambio de vía de los trenes que salen de las estaciones.

Entre los errores cometidos se encuentran:

- Tener dos recursos, uno por estación. Esto obliga a actualizar en ambos el estado del cruce. Aún en el caso de que esto se haga, uno de los recursos se actualizará antes que el otro, lo que puede dar lugar a una preferencia implícita.

- Un recurso para estación y otro para el cruce tiene un problema similar: es necesario llevar la información del cruce al recurso que modela la estación.

- Leer una petición y esperar a que se den las condiciones adecuadas para atender esa petición:

  Hay dos problemas en esta solución: el primero es que la aceptación de peticiones en el terminal se ve retrasada hasta que salga el tren anterior (porque el proceso está bloqueado en Estacion.TrenListo(i, ClaseTren, Via);), con lo que se podrían generar colas de empleados enfadados porque aunque el tren está cargado, el terminal no responde.

  Podría suponerse que el terminal tiene cierta inteligencia y ``encola'' las peticiones que le entran. Esto causa un problema adicional: en el tiempo entre que se lee una petición y se atiende, pueden haberse llenado otros trenes de mayor prioridad. Desde el punto de vista de la estación, ello significa que habiendo trenes urgentes listos para salir, están saliendo otros normales, sencillamente porque se han introducido antes sus datos.

- No diferenciar trenes urgentes y trenes normales.

- No guardar ninguna referencia a la vía en la que está un tren.

- No guardar ninguna cola de peticiones.

- Hacer llamadas bloqueantes dentro del recurso (esto paraliza el recurso durante un tiempo a priori no determinado).

- Asignar un proceso por tren: esto es una simulación que no es lo que se pedía en el enunciado. Implica, además, el acceso concurrente a los terminales de la estación. Aunque esto no está explícitamente prohibido en el enunciado, no suele ser buena idea. En muchos casos lleva a un uso incorrecto de las llamadas Terminal.LeerPeticion(i, ClaseTren, Via), en la que Via aparece como parámetro de entrada y no de salida.

Next: Implementación de un controlador Up: Examen de Programación Concurrente Previous: Examen de Programación Concurrente