Está en la página 1de 10

Colas de mensajes

LABORATORIO DE SISTEMAS INFORMTICOS EN TIEMPO REAL

Curso 2003-2004

Isidro Calvo Gordillo

-I-

INDICE

1.

Colas de mensajes..................................................................................................... 1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 Introduccin...................................................................................................... 1 Objetivos........................................................................................................... 1 Descripcin....................................................................................................... 1 Ejemplo............................................................................................................. 3 Trabajo con el cdigo del ejemplo ................................................................... 4 Modificaciones sobre el ejemplo...................................................................... 7 Ejercicio............................................................................................................ 7

2.

Informacin adicional............................................................................................... 8

Sistemas Informticos en Tiempo Real

Colas de mensajes

-1-

1. Colas de mensajes
1.1 Introduccin
Las colas de mensajes son uno de los mecanismos ms utilizados para comunicar procesos. Las colas de mensajes permiten que un nmero de mensajes, cada uno de una longitud variable, sea ordenado en una estructura de cola (FIFO o basada en prioridades) a la espera de ser ledos. Una vez que la cola ha sido creada, cualquier proceso puede escribir mensajes en la cola de mensajes as como leer mensajes de la cola de mensajes. Por tanto, es posible que varios procesos enven mensajes a una misma cola y que mltiples procesos reciban mensajes de la cola de mensajes. Normalmente para obtener comunicacin full-duplex se utilizan dos colas, una para cada direccin. Es conveniente borrar las colas de mensajes cuando no van a ser utilizadas, ya que en caso contrario se malgastar de forma innecesaria la memoria del ordenador.

1.2 Objetivos
Los objetivos principales de esta prctica son los siguientes:

Mostrar cmo utilizar las colas de mensajes para comunicar procesos en VxWorks. Familiarizarse con el uso de Wind View.

1.3 Descripcin
Las funciones relacionadas con las colas de mensajes se encuentran en la biblioteca msgLib. A continuacin se hace una breve descripcin de estas funciones: msgQCreate (int maxMsgs, int maxMsgLength, int options) Crea una cola de mensajes capaz de contener maxMsgs, cada uno de una longitud mxima de maxMsgLength bytes. Devuelve un identificador para la cola de mensajes (de tipo MSG_Q_ID) para poder usarla en las subsiguientes llamadas a las rutinas de la biblioteca. Las opciones sern una de las siguientes: MSG_Q_FIFO (0x00) Los procesos acceden a la cola por orden de peticin. MSG_Q_PRIORITY (0x01) Los procesos acceden a la cola por prioridad.

msgQDelete (MSG_Q_ID msgQId)


Borra la cola de mensajes cuyo identificador se pasa como parmetro.

Sistemas Informticos en Tiempo Real

Colas de mensajes

-2-

msgQSend (MSG_Q_ID msgQId, char *buffer, UINT nBytes, int timeout,


int priority) Enva el mensaje apuntado por buffer de longitud nBytes a la cola de mensajes msgQId. Si hay tareas esperando a recibir mensajes en la cola, el mensaje se enviar al la primera tarea que est esperando. En caso contrario el mensaje se guarda en la cola de mensajes. El parmetro timeout especifica el tiempo (en nmero de ticks del reloj del sistema por segundo) que hay que esperar para liberar el espacio en caso de que la cola de mensajes se llene. Este parmetro puede tomar los siguientes valores: NO_WAIT (0) WAIT_FOREVER (-1) La funcin msgQSend se acaba inmediatamente, incluso si el mensaje no ha sido enviado. Nunca se produce un time out.

La prioridad puede tomar los siguientes valores: MSG_PRI_NORMAL (0) Prioridad normal, se aade el mensaje al final de la cola de mensajes. MSG_PRI_URGENT (1) Prioridad urgente, aade los mensajes al principio de la cola de mensajes.

msgQReceive (MSG_Q_ID msgQId, char *buffer, UINT nBytes, int timeout)


Esta funcin lleva a cabo la tarea de recibir un mensaje de la cola de mensajes msgQId. Los parmetros *buffer y nBytes tienen un significado similar al caso anterior. El parmetro timeout especifica el tiempo que hay que esperar para que llegue un mensaje a la cola de mensajes. Este parmetro puede tomar los siguientes valores: NO_WAIT (0) WAIT_FOREVER (-1) Si no hay mensajes en la cola no se espera a que llegue ninguno. Se espera indefinidamente hasta que llegue algn mensaje a la cola.

msgQNumMsgs (MSG_Q_ID msgQId)


Devuelve el nmero de mensajes que hay en la cola en un momento dado..

Sistemas Informticos en Tiempo Real

Colas de mensajes

-3-

1.4 Ejemplo
El siguiente ejemplo permite que una tarea enve un mensaje a la cola y otra tarea reciba el mensaje:
/* includes */ #include <stdio.h> #include "vxWorks.h" #include "msgQLib.h" #include "taskLib.h"

/* prototipos de funcion */ void EscribeMsg (void) ; void LeeMsg (void) ; /* defines */ #define MAX_MESSAGES 2 #define MAX_MESSAGE_LENGTH 50 /* globales */ MSG_Q_ID mesgQueueId ; void Colas(void) /* funcin para crear una cola de mensajes y dos tareas */ { int t_IdEscribe, t_IdLee ; /* creacion de la cola de mensajes */ if ((mesgQueueId = msgQCreate(MAX_MESSAGES,MAX_MESSAGE_LENGTH,MSG_Q_FIFO))== NULL) printf("fallo en msgQCreate\n") ; printf("El identificador de la cola de mensajes es: %x\n", (unsigned int)mesgQueueId) ;

/* generacion de las dos tareas que utilizaran la cola de mensajes */ if((t_IdEscribe = taskSpawn("EscribeMsg", 90, 0x100, 2000, (FUNCPTR)EscribeMsg, 0,0,0,0,0,0,0,0,0,0)) == ERROR) printf("fallo en taskSpawn taskOne\n") ; if((t_IdLee = taskSpawn("LeeMsg",90,0x100,2000,(FUNCPTR)LeeMsg,0,0,0,0,0,0,0,0,0,0)) == ERROR) printf("fallo en taskSpawn taskTwo\n") ; } /* Colas */

void EscribeMsg(void) /* tarea que escribe en la cola de mensajes */ { char message[] = "Mensaje recibido de la tarea EscribeMsg"; /* envio del mensaje */ if( (msgQSend(mesgQueueId,message,MAX_MESSAGE_LENGTH, WAIT_FOREVER, MSG_PRI_NORMAL)) == ERROR) printf("fallo de msgQSend en EscribeMsg\n"); } /* EscribeMsg */ void LeeMsg(void) /* tarea que lee de la cola de mensajes */ { char msgBuf[MAX_MESSAGE_LENGTH]; /* recepcion del mensaje */ if (msgQReceive(mesgQueueId,msgBuf,MAX_MESSAGE_LENGTH, WAIT_FOREVER) == ERROR) printf("fallo de msgQReceive en LeeMsg\n"); else printf("%s\n",msgBuf); msgQDelete(mesgQueueId); /* eliminacion de la cola de mensajes */ } /* LeeMsg */

Sistemas Informticos en Tiempo Real

Colas de mensajes

-4-

1.5 Trabajo con el cdigo del ejemplo


1. 2. 3. 4. Copiar el cdigo fuente del ejemplo y compilarlo. Cargar el fichero objeto en la mquina target (o en el simulador del target). Ejecutar la rutina principal del ejemplo ("Colas") en el terminal WindSh. Ejecutar WindView para ver los eventos que tienen lugar durante la ejecucin del programa. a. Arrancar WindView: b. Antes de arrancar el programa Colas desde la shell de Tornado empezar a recoger eventos (Para ello pulsar el botn de Go):

c. Ejecutar el programa Colas desde la shell de Tornado. Nota: Asegurarse de redirigir la E/S mediante el comando de la shell: ? shConfig SH_GET_TASK_IO off d. Parar WindView, para ello pulsar sobre el botn de Stop situado al lado del de Go. (Es aconsejable realizar esta operacin rpidamente, para no sobrecargar la memoria con datos) e. Visualizar los eventos recogidos durante la ejecucin del programa, para ello pulsar sobre:

Sistemas Informticos en Tiempo Real

Colas de mensajes f. Obteniendo el siguiente grfico:

-5-

En este grfico pueden observarse los eventos sucedidos durante la ejecucin del programa para todas las tareas en ejecucin. g. Buscando con las barras de avance rpido y eliminando del grfico las tareas no interesan, debera obtenerse un grfico como el siguiente:

h. Poniendo el fondo en blanco y eliminando del grfico todos los eventos salvo los relacionados con los mensajes

Sistemas Informticos en Tiempo Real

Colas de mensajes Debera obtenerse un grfico como el siguiente:

-6-

msQCreate

msQSend

msQReceive

En este grfico pueden observarse los eventos, relacionados con los mensajes, sucedidos durante la ejecucin del programa para las tareas t13 (Colas), EscribeMsg y LeeMsg. NOTA: Pulsando con el botn derecho del ratn sobre la figura se obtiene una ventana en la que se proporciona el significado de los distintos eventos.

Sistemas Informticos en Tiempo Real

Colas de mensajes

-7-

1.6 Modificaciones sobre el ejemplo


Modificacin 1 Cambiar la prioridad con la que se ejecutan las tareas, de forma que la tarea de lectura sea ms prioritaria que la de escritura. Ejecutar de nuevo y visualizar el resultado con WindView. Por qu se detiene la ejecucin de la tarea LeeMsg? Modificacin 2 Sobre la Modificacin 1. En la tarea que lee los mensajes, cambiar WAIT_FOREVER por NO_WAIT. Ejecutar y estudiar el grfico con WindView. Observar la consola del sistema. Por qu se producen sendos errores? Modificacin 3 Sobre la Modificacin 1. En la tarea que lee los mensajes, cambiar WAIT_FOREVER por un determinado intervalo de tiempo, p.e. 0.2 segundos. Para comprobar que la tarea LeeMsg espera, retrasar 0.1 segundos el envo de un mensaje por la tarea EscribeMsg. De nuevo, estudiar los eventos con WindView. NOTA: Mediante la funcin taskDelay (int ticks) se puede retrasar la ejecucin de una tarea durante un determinado nmero de ticks de reloj. La funcin sysClkRateGet (void) obtiene el nmero de ticks por segundo.

1.7 Ejercicio
Basndose en el ejemplo anterior escribir cuatro tareas que hagan lo siguiente: 1. Tarea void LanzarTareas(void): Esta tarea se encarga de crear la cola de mensajes. La cola de mensajes tendr los siguientes parmetros: a) N mximo de mensajes = 2 b) Longitud mxima del mensaje = 50 caracteres c) Los mensajes accedern a la cola por orden de llegada. Esta tarea tambin se encargar de arrancar (con taskSpawn) el resto de las tareas. 2. Tarea void EnviaMensajes1 (void): Esta tarea tarea escribe 3 mensajes en la cola de mensajes. Los mensajes se escribirn con prioridad normal. El mensaje enviado a la cola contendr informacin acerca de quin es el emisor, as como un nmero de orden. 3. Tarea void EnviaMensajes2 (void): Esta tarea ser paralela a EnviaMensajes1, cambiando el mensaje enviado a la cola de mensajes.

Sistemas Informticos en Tiempo Real

Colas de mensajes

-8-

4. Tarea void LeeMensajes (void): Esta tarea leer de la cola de mensajes 6 mensajes (3 enviados por EnviaMensajes1 y 3 enviados por EnviaMensajes2). En caso de que el mensaje sea ledo correctamente se mostrar por pantalla, en caso contrario se mostrar un mensaje de error. La tarea de lectura tendr mayor prioridad que las tareas de EnviaMensajesX. P.e. que la prioriodad de LeeMensajes sea 80 frente a una prioridad de 90 para EnviaMensajesX. Ejecutar el cdigo y visualizar los eventos sucedidos con WindView. Observar los mensajes que aparecen por la consola de WindView. Modificar el cdigo anterior para que todas las tareas tengan la misma prioridad y aumentar el nmero de mensajes enviados por cada tarea a 4 mensajes en lugar de 3. Modificar el cdigo anterior de forma que la tarea de leer mensajes ceda la CPU cada vez que lee un mensaje. (Para ello utilizar un taskDelay (sysClkRateGet()*0.05))

2. Informacin adicional
Consultar el VxWorks User's Manual (disponible en versin electrnica desde el entorno de programacin de Tornado) y el Reference Manual.

Sistemas Informticos en Tiempo Real