asignación del trabajo final de programación concurrente


Hoy me han asignado el trabajo final de la asignatura de programación concurrente del máster en computación que estoy realizando en la Universidad de Cantabria. Mediante la resolución y presentación de este trabajo voy a ser evaluado en la asignatura. En el archivo comprimido que he recibido por correo electrónico se encuentra una implementación secuencial de la aplicación y un documento de ocho páginas en el que se explica el objeto del mismo:

El objetivo de este trabajo es diseñar un driver que facilite el uso de una tarjeta de entrada y salida analógica con 8 líneas analógicas de entrada y 4 líneas analógicas de salida, por aplicaciones concurrentes, así como el diseño de las aplicaciones concurrentes que hacen uso de ellas.

Los drivers son unas piezas de software, normalmente integradas en el sistema operativo, que suelen hacer uso intensivo de los threads. Aquí hay que tener en cuenta que no importa tanto entender la especificación del mismo como la implementación secuencial para poder convertirla en una implementación concurrente. El trabajo debe ser terminado este mes de noviembre. El resultado va a ser el código de la implementación concurrente y una presentación para ser defender la solución adoptada ante el profesor responsable de la asignatura.

3 comentarios en “asignación del trabajo final de programación concurrente

  1. Lectura del documento de especificación de la práctica

    La tarjeta está representada por un interfaz que permite acceder a sus registros e implementar el patrón de diseño observer manteniendo una lista de objetos que desean saber el estado de la tarjeta. Para ello los objetos que quieren estar al tanto deben registrarse con el método addInterruptListener() e implementar el interfaz AnalogIOListener (el método newChange())

    Cada vez que cambie una de las líneas de entrada/salida de la tarjeta esta invocará el método newChange() en cada uno de los objetos registrados. El objeto AnalogIOGUI implementa el interfaz de la tarjeta y permite simular la tarjeta con un bonito interfaz gráfico.

    Se describen los diagramas de secuencias que tiene que seguir un driver para leer un valor analógico o escribir un valor en la salida de la tarjeta. Yo en principio pensé que el driver era el objeto concurrente activo que utilizaba la tarjeta que se podía considerar como un objeto compartido. Pero el hecho es que el driver es el objeto pasivo compartido que accede de forma exclusiva al objeto tarjeta. Es el objeto driver (AnalogIODriver) es por tanto el que deberá implementar los mecanismos adecuados para habilitar a procesos concurrentes el acceso de la tarjeta (AnalogGUI) y su funcionalidad. La tarjeta está relacionada con el driver mediante una relación de agregación con multiplicidad uno.

    Los métodos que implementa el driver son los que cabrían esperar (lectura y escritura de entradas y salidas, respectivamente) Además implementa dos funciones bloqueantes que esperan un evento en una entrada analógica (un valor de umbral que se alcance, o se baje de un valor del mismo) y una función no bloqueante llamada generate() que genera una forma de onda a partir de su definición en un vector (por secuencia de valores) que se refleja en una de las salidas de la tarjeta (a especificar)

    Hay también una excepción que se dispara si el valor que se pasa al parámetro line que tienen todos los métodos se sale de un rango que va de 0 a 31. No entiendo muy bien el uso que puede tener esto. Dicho parámetro se utiliza para especificar la línea sobre la que desea actuar (en lectura o en escritura) Que yo sepa según la especificación del problema se tienen ocho líneas de entrada (que tienen asignados números de 0 a 7) y cuatro líneas de salida (de 0 a 3)

    En la implementación de AnalogIODriver que se suministra como punto de partida no tiene implementados los métodos bloqueantes de espera a eventos ni la función generate(). Además se tiene un ejemplo de aplicación cliente que crea una instancia de la tarjeta (AnalogIOGUI) y el driver (AnalogIODriver) asociado a la tarjeta, que hace de manera secuencial que las líneas de salida se pongan a unos valores y cuando se pasa por el valor 5V en la entrada 0 se muestra en la consola el estado actual de todas las entradas.

    El trabajo a realizar se divide en tres fases:

    (1) Introducir los elementos de sincronización en las funciones de lectura y escritura de valores en las líneas (AnalogIODriver)

    (2) Implementar la función generate() utilizando un thread por cada invocación del método (estos parecen que van a ser lo que hagan concurrencia) Para ello vamos a definir un array de objetos activos (WaveFormGenerator) que van a controlar una de las salidas (la que coincida con su indice)

    NOTA: Además hay que implementar una aplicación cliente que genere cuatro salidas (formas de onda) de forma simultánea (una por cada salida)

    (3) Implementar los métodos bloqueantes de espera a paso por valor utilizando las interrupciones generadas por la tarjeta de la tarjeta (patrón observer, objetos Listener) Los threads que las invoquen deben suspenderse esperando que las tensiones alcancen el threshold.

    NOTA: hay que crear un programa que lanza ocho procesos concurrentes que se quedaran suspendidos a la espera de que ocurra un evento sobre una entrada.

  2. Fase I: revisión de readInputLine(), setOutputLine() y readOutputLine() para permitir la programación concurrente con el objeto AnalogIODriver.

    Para esto vamos a utilizar el lock que viene con el objeto AnalogIODriver por ser de una clase java que desciende de Object. Los tres métodos citados actúan de alguna manera sobre el estado del objeto AnalogIODriver que debe de ser preservado de accesos concurrentes que le puedan dejar inconsistente. Además la aplicación de esos métodos puede requerir que el estado del objeto sea uno determinado (precondición) y dejar dicho estado en uno determinado (postcondición) La palabra clave del lenguaje java synchronized nos va a permitir convertir a los métodos citados en thread-safe.

    * readInputline(line): Retorna el valor en voltios que está establecida en
    la línea analógica de entrada que se especifica con el parámetro line. Para esto tiene que seguir un protocolo: “leer un valor analógico de la tarjeta analogIOCard” (p. 4 del guión de la práctica), es decir, NO es una operación atómica (!!) => debe ser synchronized.

    * setOutputLine(line, value): Establece la tensión en voltios expresada por
    el parámetro value en la línea analógica de salida especificada con el parámetro line. Para esto tiene que seguir un protocolo: “establecer un valor analógico en una línea analógica de salida de la tarjeta AnalogIOCard” (p. 4 del guión de la práctica), es decir, NO es una operación atómica (!!) => debe ser sincronized.

    * readOutputLine(): Retorna el valor en voltios que tiene establecida
    la línea analógica de salida especificada por el parámetro line. Para esto usa un variable de estado interna del driver (no de la tarjeta), que se accede para escritura en setOutputLine() Esto significa que la lectura y escritura de esa variable deben de estar sincronizadas para evitar que el valor cambie mientras se lee => ambas deben ser synchronized.

  3. Fase II: implementar generate()

    generate (line, period, waveform): Método no bloqueante que inicia la generación de la forma de onda que se especifica en el parámetro waveform, en la línea analógica de salida que se especifica por el parámetro line, con el tiempo de periodo que se especifica en el parámetro period. La forma de onda se especifica como un Vector de N valores analógicos expresados en voltios.

    Cada vez que se llame a esa función se debe crear un thread que la ejecute (el objeto será una instancia de la clase WaveFormGenerator) Su ejecución va a suponer una secuencia de llamadas por cada valor que se tenga que poner en la salida a partir del vector de valores analógicos. Esa secuencia debe de ser atómica, es decir, no se puede iniciar otra forma de onda sobre esa línea sin acabar la que se encuentra en curso. Como se tienen cuatro salidas se pueden tener hasta cuatro generaciones simultáneas (threads) de ondas. Esta es la concurrencia que vamos a tener en AnalogIODriver y a razón de proteger los métodos en la fase I.

    Nos dan el diagrama UML de implementación y los pasos a seguir: incluir un array de objetos WaveFormGenerator (un elemento por salida), escribir el código del mencionado objeto activo/thread WaveFormGenerator (constructor, run y finish?), reimplementar el método setOutputLine() y escribir el de generate().

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s