Sie sind auf Seite 1von 3

29/9/2014

Colas de mensajes en C para Linux

Ejemplos java y C/linux

Bsqueda
0

Twittear

Web

chuidiang.com

Tutoriales
Java

Colas de Mensajes en C para Linux

C/C++ de Linux
Metodolog
as y diseo
orientado a objetos
CSS

Enlaces
Diario de Programacin
Ms de Java
Chuwiki
Micro entradas
Foro de Java y C++
Mis proyectos
Pasatiempos

Licencia

Esta obra est bajo una


licencia de Creative
Commons.
Para reconocer la autora
debes poner el enlace
http://www.chuidiang.com

Las colas de mensajes, junto con los semforos y la memoria compartida son los recursos
compartidos que pone unix a disposicin de los programas para que puedan intercambiarse
informacin.
En C para unix es posible hacer que dos procesos (dos programas) distintos sean capaces
de enviarse mensajes (estructuras de datos) y de esta forma pueden intercambiar
informacin. El mecanismo para conseguirlo es el de una cola de mensajes. Los procesos
introducen mensajes en la cola y se van almacenando en ella. Cuando un proceso extrae un
mensaje de la cola, extrae el primer mensaje que se introdujo y dicho mensaje se borra de la
cola.
Tambin es posible hacer "tipos" de mensajes distintos, de forma que cada tipo de mensaje
contiene una informacin distinta y va identificado por un entero. Por ejemplo, los mensajes
de tipo 1 pueden contener el saldo de una cuenta de banco y el nmero de dicha cuenta, los
de tipo 2 puden contener el nombre de una sucursal bancaria y su calle, etc. Los procesos
luego pueden retirar mensajes de la cola selectivamente por su tipo. Si un proceso slo est
intersado en saldos de cuentas, extraera nicamente mensajes de tipo 1, etc.

La forma de conseguir una cola de mensajes en un programa es la siguiente:

http://www.chuidiang.com/clinux/ipcs/colas.php

En primer lugar necesitamos conseguir una clave, de tipo key_t, que sea comn para
todos los programas que quieran compartir la cola de mensajes. Para ello existe la
funcin key_t ftok (char *, int). A dicha funcin se le pasa un fichero que exista y sea
accesible y un entero. Con ellos construye una clave que nos devuelve. Si todos los
programas utilizan el mismo fichero y el mismo entero, obtendrn la misma clave.
Es habitual como primer parmetro pasar algn fichero del sistema que sepamos seguro
de su existencia, como por ejemplo "/bin/ls", que es el "ls" del unix.
Para el entero, bastara con poner un #define en algn fichero.h de forma que todos los
programas que vayan a utilizar la misma cola incluyan dicho fichero y utilicen como
entero el del #define.
Una vez obtenida la clave, se crea la cola de mensajes. Para ello est la funcin int
msgget (key_t, int). Con dicha funcin creamos la cola y nos devuelve un identificador
para la misma.
Si la cola correspondiente a la Clave key_t ya estuviera creada, simplemente nos dara el
identificdor de la misma (siempre y cuando los parmetros no indiquen lo contrario).
El primer parmetro es la clave key_t obtenida anteriormente y que debera ser la misma
para todos los programas.
El segundo parmetro son unos flags. Aunque hay ms posibilidades, lo imprescindible
es:
9 bits menos significativos, son permisos de lectura/escritura/ejecucin para
1/3

29/9/2014

Colas de mensajes en C para Linux

propietario/grupo/otros, al igual que los ficheros. Para obtener una cola con todos
los permisos para todo el mundo, debemos poner como parte de los flags el
nmero 0777. Es importante el cero delante, para que el nmero se interprete en
octal y queden los bits en su sitio (En C, cualquier nmero que empiece por cero,
se considera octal). El de ejecucin no tiene sentido y se ignora.
IPC_CREAT. Junto con los bits anteriores, este bit indica si se debe crear la cola
en caso de que no exista. Si est puesto, la cola se crear si no lo est ya y se
devolver el identificador.
Si no est puesto, se intentar obtener el identificador y se obtendr un error si no
est ya creada.
En resumen, los flags deberan ser algo as como 0777 | IPC_CREAT
Ya estamos en condiciones de utilizar la cola de mensajes. Para meter un mensaje en la
cola, se utiliza la funcin msgsnd (int, struct msgbuf *, int, int)
El primer parmetro entero es el identificador de la cola obtenido con msgget().
El segundo parmetro es el mensaje en s. El mensaje debe ser una estructura
cuyo primer campo sea un long. En dicho long se almacena el tipo de mensaje. El
resto de los campos pueden ser cualquier cosa que se desee enviar (otra
estructura, campos sueltos, etc). Al pasar el mensaje como parmetro, se pasa un
puntero al mensaje y se le hace un "cast" a struct msgbuf *. No hay ningn
problema en este "cast" siempre y cuando el primer campo del mensaje sea un
long.
El tercer parmetro es el tamao en bytes del mensaje exceptuando el long, es
decir, el tamao en bytes de los campos con la informacin.
El cuarto parmetro son flags. Aunque hay varias opciones, la ms habitual es
poner un 0 o bien IPC_NOWAIT. En el primer caso la llamada a la funcin queda
bloqueada hasta que se pueda enviar el mensaje. En el segundo caso, si el
mensaje no se puede enviar, se vuelve inmediatamente con un error. El motivo
habitual para que el mensaje no se pueda enviar es que la cola de mensajes est
llena.
Para recoger un mensaje de la cola se utiliza la funcin msgrcv (int, struct msgbuf *,
int, int, int).
El primer parmetro es el identificador de la cola obtenido con msgget().
El segundo parmetro es un puntero a la estructura donde se desea recoger el
mensaje. Puede ser, como en la funcin anterior, cualquier estructura cuyo primer
campo sea un long para el tipo de mensaje.
El tercer parmtro entero es el tamao de la estructura exceptuando el long.
El cuarto parmetro entero es el tipo de mensaje que se quiere retirar. Se puede
indicar un entero positivo para un tipo concreto o un 0 para cualquier tipo de
mensaje.
El quinto parmetro son flags, que habitualmente puede ser 0 o bien
IPC_NOWAIT. En el primer caso, la llamada a la funcin se queda bloqueada
hasta que haya un mensaje del tipo indicado. En el segundo caso, se vuelve
inmediatamente con un error si no hay mensaje de dicho tipo en la cola.
Una vez terminada de usar la cola, se debe liberar. Para ello se utiliza la funcin msgctl
(int, int, struct msqid_ds *). Es una funcin genrica para control de la cola de
mensajes con posibilidad de varios comandos. Aqu slo se explica como utilizarla para
destruir la cola.
El primer parmetro es el identificador de la cola de mensajes, obtenido con
msgget().
El segundo parmetro es el comando que se desea ejecutar sobre la cola, en este
http://www.chuidiang.com/clinux/ipcs/colas.php

2/3

29/9/2014

Colas de mensajes en C para Linux

caso IPC_RMID.
El tercer parmtro son datos necesarios para el comando que se quiera ejecutar.
En este caso no se necesitan datos y se pasar un NULL.
Hay una serie de comandos tiles para ver desde una shell las colas que estn abiertas,
cuntos mensajes contienen e incluso destruirlas.
El Ejemplo
Aqu hay dos fuentes de ejemplo en C sobre UNIX de colas de mensajes cola1.c y cola2.c.
cola1 abre la cola de mensajes, enva un mensaje de tipo 1 para que lo lea cola2 y espera
un mensaje de tipo 2 . Cuando llega el mensaje de tipo 2, cola1 destruye la cola de
mensajes.
Por su parte, cola2 abre la cola mensajes y espera un mensaje tipo 1. Cuando lo recibe,
enva un mensaje de tipo 2 y se sale. Deja la destruccin de la cola para cola1.
Para ejecutarlos, compilarlos en primer lugar con make cola1 cola2 (no es necesario fichero
Makefile) o bien con g++ cola1.c -o cola1 y g++ cola2.c -o cola2. Luego en dos shell
distintas, ejecutar en la primera cola1 y en la segunda cola2. Cada uno de ellos escribir el
mensaje recibido del otro.
Estadsticas y comentarios

Numero de visitas desde el 4 Feb 2007:

Esta pagina este mes: 267


Total de esta pagina: 44649
Total del sitio: 14607469

http://www.chuidiang.com/clinux/ipcs/colas.php

3/3