Tareas Comunicacion Sincronizacion I

11

Click here to load reader

Transcript of Tareas Comunicacion Sincronizacion I

Page 1: Tareas Comunicacion Sincronizacion I

Multi-Tarea y Semáforos

LABORATORIO DE SISTEMAS INFORMÁTICOS EN TIEMPO REAL

Curso 2003-2004 Fabián López Valencia

Page 2: Tareas Comunicacion Sincronizacion I

- I -

INDICE

1. Multitarea ................................................................................................................. 1

1.1 Introducción...................................................................................................... 1

1.2 Objetivos........................................................................................................... 1

1.3 Descripción....................................................................................................... 1

1.4 Creación y activación de tareas ........................................................................ 2

1.5 Ejemplo............................................................................................................. 2

1.6 Trabajo con el código del ejemplo ................................................................... 3

1.7 Modificación del ejemplo................................................................................. 4

2. Semáforos ................................................................................................................. 5

2.1 Introducción...................................................................................................... 5

2.2 Objetivo ............................................................................................................ 5

2.3 Descripción....................................................................................................... 5

2.4 Control de los semáforos .................................................................................. 6

2.5 Ejemplo: ........................................................................................................... 8

2.6 Trabajo con el código del ejemplo ................................................................... 9

2.7 Modificación del ejemplo................................................................................. 9

3. Información adicional............................................................................................... 9

Sistemas Informáticos en Tiempo Real

Page 3: Tareas Comunicacion Sincronizacion I

Tareas y mensajes - 1 -

1. Multitarea

1.1 Introducción

Los sistemas de tiempo real modernos se basan en los conceptos complementarios de multitarea y comunicación entre tareas. Un entorno multitarea permite que las aplicaciones en tiempo real se construyan como un conjunto de tareas independientes, cada una de ellas con un hilo de ejecución separado y con su propio conjunto de recursos de sistema. Las facilidades de comunicación entre tareas permiten que las tareas se sincronicen y coordinen sus actividades. El núcleo multitarea de VxWorks, wind, utiliza una planificación por prioridades, basada en interrupciones. Ofrece un rápido cambio de contexto y una baja latencia de interrupción.

1.2 Objetivos

El objetivo principal de esta primera parte de la práctica es el siguiente:

• Inicializar múltiples procesos usando las rutinas de tareas de VxWorks con diferentes prioridades.

1.3 Descripción

La multi-tarea crea la apariencia de muchos hilos de ejecución que se ejecutan en paralelo cuando, de hecho, el núcleo entrelaza su ejecución sobre la base de un algoritmo de planificación. Cada programa aparentemente independiente se llama tarea. Cada tarea tiene su propio contexto, que es el entorno de la CPU y los recursos del sistema que ve la tarea cada vez que es planificada por el núcleo para ejecutarse. En un cambio de contexto, el contexto de una tarea se guarda en el bloque de control de tarea (TCB, Task Control Block). El contexto de una tarea incluye:

• un hilo de ejecución, es decir, el contador de programa de la tarea

• los registros de CPU y los de punto flotante necesarios

• una pila de variables dinámicas y las direcciones de retorno de llamadas a función

• asignación de dispositivos E/S para la entrada, salida y salida de error estándares

• un temporizador de retardo (delay timer)

• un temporizador de rodaja de tiempo (timeslice timer)

• estructuras de control del núcleo

• manejadores de señal

• valores de depuración y monitorización de prestaciones

Sistemas Informáticos en Tiempo Real 1

Page 4: Tareas Comunicacion Sincronizacion I

Tareas y mensajes - 2 -

1.4 Creación y activación de tareas

La rutina taskSpawn crea un nuevo contexto de tarea, que incluye la creación e inicialización del entorno de la tarea para llamar a la rutina principal (una subrutina ordinaria) con los argumentos especificados. La nueva tarea comienza en la entrada de la rutina especificada. Retorna un identificador de la tarea (int), si se ha creado e inicializado con éxito, o ERROR, en caso contrario.

Sintaxis:

id = taskSpawn (nombre, prioridad, opciones, stacksize, nombrefunción, arg1, arg2, arg3, ... , arg10) ;

• nombre de la nueva tarea (una cadena de caracteres ASCII).

• prioridad (0-255). Siendo 0 la máxima prioridad y 255 la mínima

• opciones. Es un valor hexadecimal o una constante predefinida (VX_FP_TASK, VX_NO_STACK_FILL,VX_PRIVATE_ENV, VX_UNBREAKABLE).

• tamaño de la pila o stacksize en bytes (int).

• dirección o nombre de la rutina principal ejecutada por la tarea. Su tipo debe ser FUNCPTR.

• y 10 argumentos que se pasarán a la rutina principal como parámetros de arranque.

1.5 Ejemplo

Crear una tarea que muestre su nombre y su identificador:

/* librerias utilizadas */ #include <vxWorks.h> #include <taskLib.h> #include <stdio.h> /* Prototipos de funciones locales */ void print(void) ; /* funcion que se va a ser lanzada por la tarea */ int LanzarTarea (void) /* funcion que crea y lanza la tarea */ { int t_taskID ; /* ID Identificador de la tarea */ char * sNombreTarea = "tTarea_1" ; /* Nombre de la tarea */ if ( (t_taskID = taskSpawn(sNombreTarea,90,VX_FP_TASK,2000, (FUNCPTR) print,0,0,0,0,0,0,0,0,0,0)) == ERROR ) { printf ("\nNO SE HA PODIDO CREAR LA TAREA: %s\n", sNombreTarea) ; exit (-1) ; } return (0) ; } /* LanzarTarea */ void print (void) /* Muestra nombre e identificador de tarea que la ejecuta*/ { printf("\nHola, soy la tarea %s y mi ID es %d\n", taskName(taskIdSelf()), taskIdSelf()); } /* print */

Sistemas Informáticos en Tiempo Real 2

Page 5: Tareas Comunicacion Sincronizacion I

Tareas y mensajes - 3 -

1.6 Trabajo con el código del ejemplo

1. Copiar el código fuente del ejemplo y compilarlo.

2. Cargar el fichero objeto en la máquina target (o en el simulador del target).

3. Ejecutar la rutina principal del ejemplo ("LanzarTarea") en el terminal WindSh.

-> LanzarTarea

4. Lanzar una tarea que ejecute la rutina principal del ejemplo ("LanzarTarea").

a) -> sp LanzarTarea

b) -> repeat 3 , LanzarTarea

c) -> period 2 , LanzarTarea

-> i

-> td IdentificadorDeLaTarea

Ejecutar los comandos: i , iStrict y ti para ver información del TCB (Task Control Block) de las tareas en ejecución.

El comando i, muestra la siguiente información:

Campo Significado NAME Nombre de la tarea ENTRY Nombre de la función o dirección donde comienza la ejecución de la

tarea TID ID de la tarea PRI Prioridad STATUS Estado de la tarea PC Contador de programa SP Puntero de la pila o Stack pointer ERRNO El código de error más reciente de esta tarea DELAY Si la tarea tiene un retardo, número de tics de reloj que faltan en el

retardo (o 0 si no tiene retardo)

NOTA: Asegurarse de redirigir la E/S mediante el comando de la shell: -> ? shConfig SH_GET_TASK_IO off

Sistemas Informáticos en Tiempo Real 3

Page 6: Tareas Comunicacion Sincronizacion I

Tareas y mensajes - 4 -

1.7 Modificación del ejemplo

Modificación 1

Según lo indicado anteriormente, durante la llamada a taskSpawn() se pueden pasar argumentos a la función que es ejecutada por la tarea. Pasar dos argumentos (carácter y entero) y hacer que se imprima el carácter tantas veces como indica el número.

Modificación 2

Crear dos tareas como la anterior pero con distinta prioridad. Las dos tareas se deben lanzar desde un mismo subprograma “LanzarTareas”. ¿Hay alguna diferencia en la salida dependiendo de la prioridad de las tareas?

Modificación 3

Generar dos tareas “periódicas” con periodos 2 segundos y 4 segundos.

Se deben ejecutar 4 veces cada una de ellas.

NOTA: Mediante la función taskDelay (int ticks) se puede retrasar la ejecución de la tarea que la ejecuta un determinado número de ticks de reloj. Se puede utilizar la función sysClkRateGet (void) para obtener el número de ticks por segundo.

Sistemas Informáticos en Tiempo Real 4

Page 7: Tareas Comunicacion Sincronizacion I

Tareas y mensajes - 5 -

2. Semáforos

2.1 Introducción

Los semáforos permiten la sincronización y comunicación de actividades en aplicaciones multitarea. La forma más obvia para que se comuniquen las tareas es mediante estructuras de datos compartidas. Dado que en VxWorks todas las tareas se encuentran en un único espacio de direccionamiento lineal, las variables globales, los buffers lineales, los buffers en anillo, las listas enlazadas y los punteros se pueden referenciar directamente por el código que se ejecuta en contexto diferente (por diferentes tareas). Sin embargo, mientras que el espacio de direccionamiento compartido simplifica el intercambio de datos, es crucial evitar los interbloqueos en el acceso a la memoria para evitar conflictos. Existen muchos métodos para obtener el acceso exclusivo a los recursos, y uno de ellos es el empleo de semáforos.

2.2 Objetivo

El objetivo principal de esta segunda parte de la práctica es el siguiente:

• Mostrar el uso de los semáforos de VxWorks.

2.3 Descripción

Los semáforos de VxWorks están altamente optimizados y proporcionan los mecanismos más rápidos para la comunicación entre tareas. Los semáforos son el mecanismo principal para garantizar el acceso en exclusión mutua y de sincronización entre tareas. Existen tres tipos de semáforos, optimizados para su utilización en distintos tipos de problemas:

Semáforo binario

El semáforo de propósito general más rápido. Optimizado para sincronización, también puede emplearse para exclusión mutua.

Un semáforo binario se puede ver como un indicador de disponibilidad.

Cuando una tarea toma un semáforo binario, usando semTake(), el resultado depende de si el semáforo está disponible o bloqueado en el instante de la llamada a la función. Si el semáforo está disponible, entonces el semáforo pasa a bloqueado y entonces la tarea continúa ejecutándose inmediatamente. Si el semáforo está bloqueado, la tarea se pone en una cola de tareas bloqueadas e incorpora un estado de pendiente en la disponibilidad del semáforo.

Sistemas Informáticos en Tiempo Real 5

Page 8: Tareas Comunicacion Sincronizacion I

Tareas y mensajes - 6 -

Cuando una tarea libera un semáforo binario, usando semGive(), el resultado depende de si el semáforo está disponible o bloqueado en el instante de la llamada. Si el semáforo está ya disponible, “dar” el semáforo no tiene ningún efecto. Si el semáforo está bloqueado y ninguna tarea está esperando para tomarlo, entonces el semáforo pasa a estar disponible. Si el semáforo está bloqueado y una o más tareas están pendientes de su disponibilidad, entonces la primera tarea en la cola de tareas pendientes se desbloquea, y el semáforo se deja como bloqueado.

Semáforo de exclusión mutua (mutex)

Semáforo binario especial optimizado para tratar problemas inherentes a la exclusión mutua (por ejemplo en accesos a secciones críticas): Inversión de prioridades, seguridad ante la eliminación de tareas y acceso recursivo a recursos.

Semáforo contador

Generalización del semáforo binario. Inicialmente almacena el número máximo de procesos que pueden compartir el recurso de forma simultánea.

Cada vez que alguna tarea toma el semáforo el contador se decrementa y cada vez que es liberado se incrementa. Cuando el contador alcanza el valor cero, la tarea que intenta tomar el semáforo queda bloqueada.

2.4 Control de los semáforos

Los semáforos Wind proporcionan un interfaz uniforme para el control de semáforos.

Únicamente las rutinas de creación son específicas de cada tipo de semáforo:

• semBCreate (int queue_type, SEM_B_STATE initialState ): Crea e inicializa un semáforo binario.

queue_type: SEM_Q_PRIORITY indica que las tareas bloqueadas se encolan en orden de prioridad

SEM_Q_FIFO indica que las tareas bloqueadas se encolan en orden de llegada

initialState: SEM_FULL indica que el semáforo creado está disponible

SEM_EMPTY indica que el semáforo creado está bloqueado

Sistemas Informáticos en Tiempo Real 6

Page 9: Tareas Comunicacion Sincronizacion I

Tareas y mensajes - 7 -

• semMCreate (int options): Crea e inicializa un semáforo de exclusión mutua. El estado del semáforo se inicializa a FULL. El parámetro options indica la forma en que se encolan las tareas bloqueadas

options: SEM_Q_PRIORITY indica que las tareas bloqueadas se encolan en orden de prioridad

SEM_Q_FIFO indica que las tareas bloqueadas se encolan en orden de llegada

SEM_DELETE_SAFE evita que la tarea que tiene el semáforo sea borrada por otra tarea

SEM_INVERSION_SAFE protege el sistema de la inversión de prioridades. La tarea que bloquea el semáforo se ejecuta con una prioridad superior a la de todas las tareas pendientes de dicho semáforo. Esta opción tiene que ir acompañada por la de modo de encolado SEM_Q_PRIORITY.

semMCreate (SEM_Q_PRIORITY | SEM_INVERSION_SAFE);

• semCCreate (int options, int initialCount): Crea e inicializa un semáforo contador.

• semDelete (SEM_ID semId): Termina y libera un semáforo.

• semTake (SEM_ID semId, int timeout): Espera la liberación de un semáforo.

timeout (ticks de reloj) indica el tiempo máximo de bloque o de la tarea por el semáforo. También puede tomar los: WAIT_FOREVER (bloqueo indefinido) y NO_WAIT (la tarea no se bloquea)

• semGive (SEM_ID semId): Libera un semáforo.

• semFlush (SEM_ID semId): Desbloquea todas las tareas que esperan por un semáforo.

NOTA: Consultar VxWorks Reference Manual para ver los argumentos válidos de las rutinas anteriores.

Sistemas Informáticos en Tiempo Real 7

Page 10: Tareas Comunicacion Sincronizacion I

Tareas y mensajes - 8 -

2.5 Ejemplo:

En el ejemplo siguiente, dos tareas (tTarea_1 y tTarea_2), realizan diversas acciones de manera independiente (mostrar mensajes) pero hay un instante en el cual se deben sincronizar. Para lo cual la tarea que primero llega, tTarea_1, la más prioritaria, debe esperar a que la segunda llegue al punto de sincronización para poder continuar.

/* librerias utilizadas */ #include "vxWorks.h" #include "taskLib.h" #include "semLib.h" #include "stdio.h" /* prototipos de funcion */ void fTareaUna(void) ; /* funcion que va ejecutar la tarea tTarea_1 */ void fTareaDos(void) ; /* funcion que va ejecutar la tarea tTarea_2 */ /* Globales */ SEM_ID sem ; /* semaforo */ void binario (void) { int taskId_1, taskId_2 ; /* Crea un semaforo binario inicialmente bloqueado */ if ((sem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY)) == NULL) printf ("\nERROR: no se ha podido crear el semaforo"); /* spawn las dos tareas */ if ((taskId_1 = taskSpawn("tTarea_1", 80, VX_FP_TASK, 2000, (FUNCPTR) fTareaUna ,0,0,0,0,0,0,0,0,0,0)) == ERROR) printf ("\nERROR: no se ha podido crear la tarea: tTarea_1"); if ((taskId_2 = taskSpawn("tTarea_2",90, VX_FP_TASK,2000, (FUNCPTR) fTareaDos, 0,0,0,0,0,0,0,0,0,0)) == ERROR) printf ("\nERROR: no se ha podido crear la tarea: tTarea_2"); } /* binario */ void fTareaUna(void) { printf ("\n tTarea_1 antes de la sincronizacion...") ; printf ("\n** tTarea_1 llega al punto de sincronizacion y espera a tTarea_2\n"); semTake (sem,WAIT_FOREVER); /* espera indefinidamente por el semaforo */ printf ("\n tTarea_1 despues de la sincronizacion...") ; } /* fTareaUna */ void fTareaDos(void) { printf ("\n tTarea_2 antes de la sincronizacion...") ; printf ("\n ** tTarea_2 ha llegado al punto de sincronizacion\n"); semGive (sem) ; /* libera el semaforo */ printf ("\n tTarea_2 despues de la sincronizacion...") ; } /* fTareaDos*/

Sistemas Informáticos en Tiempo Real 8

Page 11: Tareas Comunicacion Sincronizacion I

Tareas y mensajes - 9 -

2.6 Trabajo con el código del ejemplo

1. Copiar el código fuente del ejemplo y compilarlo.

2. Cargar el fichero objeto en la máquina target (o en el simulador del target).

3. Ejecutar la rutina principal del ejemplo ("binario") en el terminal WindSh.

-> binario

2.7 Modificación del ejemplo Modificación 1

En el ejemplo de semáforo binario, modifica los valores de las prioridades de las tareas, los tipos de cola y de disponibilidad del semáforo y observa las diferencias de la salida.

Ejercicio 1

Variable compartida y exclusión mutua.

Crear dos tareas, t_Lectora y t_Monitor, que acceden a una misma variable utilizando el mecanismo de exclusión mutua. La tarea t_Lectora realiza 5 veces la operación de lectura de un número entero desde teclado almacenándolo en una variable y la tarea t_Monitor muestra, por la consola, el valor de dicha variable (una vez tras cada lectura).

Ejercicio 2

Escribir un programa que cree dos tareas, que de manera periódica, hagan oscilar el valor de una variable "global" entre 1 y 0.

NOTA: Se deberán hacer dos versiones; una utilizando semáforos binarios y otra utilizando semáforos mutex.

3. Información adicional Consultar el VxWorks User's Manual y el Reference Manual.

Sistemas Informáticos en Tiempo Real 9