Вы находитесь на странице: 1из 7

Colas de Mensajes

Conceptos generales. Creacin de una cola de mensajes. msgget Control de una cola de mensajes. msgctl Ejemplo de eliminacin de una cola. Escribir en colas de mensajes. msgsnd Leer de colas de mensajes. msgrcv Ejemplo cliente-servidor.

Computadores E.T.S.Ing.Indust. Prof.Eusebio de la Fuente

P3.1

Colas de Mensajes

Conceptos generales

Una cola de mensajes es una estructura de datos gestionada por el kernel, en la cual van a poder escribir y leer los procesos que se ejecuten en el sistema. Los mecanismos de sincronizacin para que no se produzca colisin son responsabilidad del kernel. Los datos que se escriben en la cola deben tener formato de mensaje y son tratados como un todo indivisible. La estructura de datos que forma la cola de mensajes tiene una forma definida: un identificador un campo que marca el tipo de mensaje un rea de datos. A una cola de mensajes puede acceder cualquier proceso que conozca su identificador y tenga los permisos necesarios, pudiendo leer y escribir en ella.

Computadores E.T.S.Ing.Indust. Prof.Eusebio de la Fuente

P3.2

Colas de Mensajes

Conceptos generales

El kernel gestiona las colas de mensajes como un mecanismo FIFO (first input, first output), es decir, el primer mensaje escrito en la cola ser el primero en salir de ella al realizar una lectura. Sin embargo, para dotar de ms flexibilidad, se pueden hacer peticiones de lectura que extraigan mensajes de un tipo determinado, con lo que se rompe la gestin de tipo FIFO, aunque sta se sigue manteniendo para todos aquellos mensajes que son de un mismo tipo. Esta clasificacin de los mensajes por tipos permite distinguir cules son los mensajes que van destinados a cada uno de los procesos lectores.

Computadores E.T.S.Ing.Indust. Prof.Eusebio de la Fuente

P3.3

Colas de Mensajes

Creacin de una cola. msgget

La funcin msgget permite crear una cola de mensajes o habilitar el acceso a una ya existente. Su declaracin es la siguiente: int msgget (clave, opcin); key_t clave; int opcin; /* clave de la cola de mensajes */ /* opcin para la creacin */

Si la llamada funciona correctamente, devolver el identificador de la cola de mensajes creada o habilitada;

El primer parmetro, clave, es la llave de acceso, El parmetro opcin es una mscara de bits con la que se define los permisos de acceso a la cola de mensajes y el modo de adquirir el identificador de la misma.

Computadores E.T.S.Ing.Indust. Prof.Eusebio de la Fuente

P3.4

Colas de Mensajes

Creacin de una cola. Ejemplo


#define LLAVE 1234 #define PERMS 0600 /* clave de acceso */ /* permisos de acceso */

int msqid; if(msgid== -1) {

/* identificador de la nueva cola de mensajes */

msqid=msgget(LLAVE, IPC_CREAT | PERMS);

/* Error al crear la cola. Tratamiento del error. */ printf(Error al crear la cola\n); exit(1); }

Computadores E.T.S.Ing.Indust. Prof.Eusebio de la Fuente

P3.5

Colas de Mensajes

Control de una cola. msgctl

La funcin msgctl proporciona informacin administrativa y de control sobre la cola de mensajes que se especifique. Su declaracin es la siguiente: int msgctl (msqid, op, p_buf); int msqid; /* identificador de la cola de mensajes */ int op; /* operacin a efectuar */ struct msqid_ds *p_buf; /* argumento de la operacin */ Esta funcin acta sobre la cola de mensajes cuyo identificador es msquid (identificador que devolvi la llamada a la funcin msgget). El segundo parmetro op indica el tipo de operacin de control que se desea realizar. Sus posibles valores son: IPC_STAT: lee la cabecera de la cola de mensajes IPC_SET: establece distintos valores, como usuarios, permisos, etc, de la cola. IPC_RMID: elimina la cola de mensajes.

Computadores E.T.S.Ing.Indust. Prof.Eusebio de la Fuente

P3.6

Colas de Mensajes

Eliminacin de una cola. Ejemplo

El siguiente trozo de cdigo muestra como se borra una cola de mensajes previamente creada:

int msqid; ....

/* identificador de la cola de mensajes */

msgctl (msqid, IPC_RMID,0);

Computadores E.T.S.Ing.Indust. Prof.Eusebio de la Fuente

P3.7

Colas de Mensajes

Leer y escribir en colas

Una vez habilitada la cola, los procesos fundamentalmente se dedicarn a enviar y a recibir mensajes por medio de ella. Hay que hacer notar que los procesos que hayan habilitado una cola de mensajes pueden enviar y recibir mensajes indistintamente (siempre que los permisos lo permitan), no vindose limitados a realizar una sola funcin. Una cuestin interesante en cuanto a la recepcin de los mensajes es que el proceso receptor tiene que especificar qu tipo de mensaje quiere recibir, entregndole el sistema el primer mensaje de ese tipo que haya en la cola. Esto permite que mltiples procesos compartan la misma cola, sin interferir entre ellos ni quitarse los mensajes unos a otros.

Computadores E.T.S.Ing.Indust. Prof.Eusebio de la Fuente

P3.8

Colas de Mensajes

Escribir en colas de mensajes. msgsnd

La llamada al sistema que permiten realizar la escritura o envo es msgsnd. Su declaracin es: int msgsnd (msqid, p_mes, lg, opcion); int msqid; struct msgbuf *p_mes; int lg; int opcion; /* identificador de la cola de mensajes */ /* puntero al mensaje a enviar */ /* longitud del mensaje */ /* opcin de la emisin */

msqid es el identificador de la cola de mensajes. p_mes apunta a la zona de memoria, que contiene el mensaje a enviar. p_mes es una estructura de tipo msgbuf que normalmente contiene dos campos: el primer campo debe ser de tipo long e identifica el tipo de mensaje y el segundo, contendr la informacin a transmitir, cuyo tamao es variable. El parmetro lg contiene el tamao, en bytes, del mensaje, es decir, sin tener en cuenta el espacio que ocupa el long del tipo del mensaje. Por ltimo, el parmetro opcion es una mscara de bits que permite especificar el comportamiento del proceso emisor en el caso de que no pueda enviarse el mensaje por causa de la carga del mecanismo de colas de mensajes (demasiados mensajes o cola llena). Por defecto, en estas circunstancias la funcin es bloqueante (detiene la ejecucin del proceso emisor). Dicho proceso se despertar cuando sea posible la escritura del mensaje en la cola. Sin embargo, si el bit IPC_NOWAIT est activo, la llamada es no bloqueante, es decir; la llamada devuelve el control inmediatamente y retorna el valor -1 informando de que no ha sido posible colocar el mensaje en la cola.

Computadores E.T.S.Ing.Indust. Prof.Eusebio de la Fuente

P3.9

Colas de Mensajes

Leer de colas de mensajes. msgrcv

msgrcv permite extraer un mensaje de una cola y almacenar su contenido en una direccin especificada. Su declaracin es: int msgrcv (msqid, p_mes, lgmax, tipo, opcion); int msqid; struct msgbuf *p_mes; int lgmax; long tipo; int opcion; /* identificador de la cola de mensajes */ /* puntero a la zona reservada */ /* longitud mxima que se puede aceptar */ /* tipo del mensaje esperado */ /* opcin de la recepcin */

msqid especifica el identificador de la cola de mensajes de la cual se pretende leer un mensaje. El parmetro lgmax indica el tamao mximo del mensaje que se puede extraer (ste depender esencialmente del tamao del espacio reservado para el mensaje sin contar los bytes que ocupa el tipo de mensaje). El parmetro tipo indica qu mensaje se quiere extraer (para ello se compara su valor con el campo tipo de la estructura de cada mensaje). si queremos recibir el primer mensaje que haya en la cola, independientemente del tipo que indique, podemos hacerlo indicando un tipo igual a 0. Por defecto, la llamada a esta funcin es bloqueante, es decir; el proceso que la invoca se suspende si no existe ningn mensaje en la cola que tenga un identificador de tipo particular coincidente con el parmetro tipo, y se despertar cuando llegue un mensaje que satisfaga la peticin. Sin embargo, si el parmetro opcin especifica que el bit IPC_NOWAIT esta activo, entonces la llamada devuelve inmediatamente el control y retorna el valor -1 indicando que no ha sido posible leer un mensaje de las caractersticas especificadas.

Computadores E.T.S.Ing.Indust. Prof.Eusebio de la Fuente

P3.10

Colas de Mensajes

Ejemplo
#define LLAVE 1234 #define MAX 20 int msqid; struct { long tipo; char cadena[MAX]; } mensaje; int longitud; .... /* Creacin de la cola de mensajes */ msqid=msgget(LLAVE, IPC_CREAT | 0600); /* Envio de un mensaje */ mensaje.tipo=1; strcpy(mensaje.cadena, hola); longitud=sizeof(mensaje)-sizeof(mensaje.tipo); msgsnd(msqid, &mensaje, longitud, 0); .. /* Recepcin del mensaje */ msgrcv(msqid, &mensaje, longitud, 1, 0) ; printf(El mensaje leido es %s\n, mensaje.cadena); /* Eliminacin de la cola de mensajes */ msgctl(msqid, IPCRMID, 0);
Computadores E.T.S.Ing.Indust. Prof.Eusebio de la Fuente

...

P3.11

Colas de Mensajes

Ejemplo Cdigo Servidor


/*----------------------- COLAS DE MENSAJES. SERVIDOR. Transforma a maysculas -------------------*/ /* Cdigo minimo del servidor. No contiene comprobacin de errores! */ #include "mensaje.h" main() { int readid, writeid; struct mens_peticion peticion; struct mens_respuesta respuesta; /* -----------Crea las colas de mensajes--------------------- */ readid = msgget(MKEY1, PERMS | IPC_CREAT); writeid = msgget(MKEY2, PERMS | IPC_CREAT); while(peticion.letra!='*') { /*-----------Espera la peticion de un cliente---------*/ msgrcv(readid,&peticion,sizeof(char),0,0); printf("Soy el servidor %d. He recibido la letra %c\n",getpid(),peticion.letra); respuesta.mayuscula=toupper(peticion.letra); printf("Serv:La respuesta que voy a mandar es %c\n", respuesta.mayuscula); /*-----------Espera la peticion de un cliente---------*/ msgsnd(writeid, &respuesta, sizeof(char),0); } /* Ya hemos acabado y hay que borrar las dos colas que hemos creado */ msgctl(writeid, IPC_RMID, 0); msgctl(readid, IPC_RMID, 0); } Computadores E.T.S.Ing.Indust. Prof.Eusebio de la Fuente P3.12 Colas de Mensajes

Ejemplo Cdigo Cliente


/*----------------------- COLAS DE MENSAJES. CLIENTE. Enva minsculas /* Cdigo minimo del cliente. No contiene comprobacin de errores! */ #include main() { int readid, writeid; struct mens_peticion peticion; struct mens_respuesta respuesta; char retorno; /* Abre las colas de mensaje. El servidor ha tenido que crearlas antes! */ writeid = msgget(MKEY1, 0); readid = msgget(MKEY2, 0 ); /*----------- se repite hasta introducir * --------------------------*/ do { printf("Intro letra \n"); fflush(stdin); scanf("%c",&peticion.letra); scanf("%c",&retorno); /* ----------enva la letra a la cola-------------- */ msgsnd(writeid,&peticion,sizeof(char),0); printf("Soy el cliente %d. He mandado la letra %c\n",getpid(),peticion.letra); /* ------queda a la espera para leer el result------*/ msgrcv(readid, &respuesta, sizeof(char),0,0); printf("Soy el cliente %d. y he recibido la letra %c\n",getpid(),respuesta.mayuscula); }while(peticion.letra!='*'); } Computadores E.T.S.Ing.Indust. Prof.Eusebio de la Fuente P3.13 Colas de Mensajes "mensaje.h" -------------------*/

mensaje.h
#include <stdio.h> #include <stdlib.h> #include <sys/ipc.h> #include <sys/msg.h> #include <sys/errno.h> #define MKEY1 1111L #define MKEY2 2222L #define PERMS 0666 struct mens_peticion { long tipo; char letra; }; struct mens_respuesta { long tipo; char mayuscula; };

Computadores E.T.S.Ing.Indust. Prof.Eusebio de la Fuente

P3.14

Colas de Mensajes

Вам также может понравиться