3. Mensajería
Un mensaje es un contenedor que se emplea para
intercambiar información entre dos o más procesos. Los
mensajes tienen un cierto formato generalmente compuesto
por una cabecera, que contiene información sobre la fuente
y el destinatario, y un cuerpo, que contiene información
específica.
Los mecanismos de mensajería se refiere al conjunto de
funcionalidades que permiten al sistema operativo realizar
la entrega de un mensaje a uno o varios procesos. Mediante
dicho mecanismo también es posible resolver problemas de
concurrencia.
4. Los sistemas operativos generalmente ofrecen dos
llamadas al sistema para que un proceso pueda enviar y
recibir mensajes:
Send (destino, mensaje): Envía un mensaje a un destino.
Receive (fuente, mensaje): Recibe un mensaje de una
fuente.
Una operación compuesta derivada de las primitivas
básicas es:
Sendrec (dest_fuent, mensaje): Envía un mensaje a un
destino y recoge la respuesta.
Cualquier proceso que necesite comprobar si tiene
mensajes para ser procesados por él debe invocar la
llamada al sistema recv.
5. Formas de identificación
Para identificar la fuente y el destino de nuestro mensaje se pueden
emplear dos estrategias.
Denominación Directa
En este caso se emplea un ID que permite identificar a la fuente y al
destinatario de manera unívoca en el sistema, la denominación
directa permite tres configuraciones:
Unicast, de manera que la comunicación sucede entre una fuente y
un destinatario.
Broadcast, el emisor envía un mensaje a todos los procesos
existentes en el sistema.
Multicast, el emisor envía un mensaje a un grupo de procesos, siendo
un grupo un subconjunto de procesos existentes en el sistema.
El principal inconveniente de la denominación directa es que se
pierde el mensaje si el destino no se encuentra.
6. Denominación Indirecta
Se emplea un elemento intermediario denominado buzón. El sistema
operativo ofrece llamadas al sistema que permiten la creación y
destrucción de buzones, por
ejemplo, CreateMailbox y DestroyMailbox. Una vez creado el
buzón, se emplea éste para realizar la comunicación entre procesos.
Con los buzones se pueden emplear cuatro formas diferentes de
comunicación:
Buzón limitado : De un proceso a otro.
Buzón de entrada: De varios a uno.
Buzón de salida: De uno a varios.
Buzón múltiple: Varios procesos entre sí con el mismo buzón.
El receptor no conoce la identidad de quien envía el mensaje, a
menos que el SO se haya encargado de ello. El problema surge
cuando un proceso intruso y éste lee los mensajes de los buzones.
7. Formas de transmisión
Distinguimos tres formas de transmisión: Transmisión por copia,
transmisión por referencia y transmisión por copia en caso de
escritura.
Transmisión por copia
Si se emplea denominación directa, al invocar el receptor la
llamada recv, el mensaje se copia del espacio de memoria del
emisor al espacio de receptor. Esta forma de implementar la
transmisión tiene un coste de orden lineal <math>O(n)</math>
.
Si se emplea denominación indirecta, al invocar send el emisor, el
mensaje se copia del espacio de emisor al espacio del buzón, que se
encuentra en el espacio de memoria del sistema operativo. Una vez
que el receptor invoca receive, se copia el mensaje al espacio de
memoria que el receptor ha habilitado para almacenar el mensaje.
8. Transmisión por referencia
Es una mejora frente al mecanismo de transmisión por copia.
Básicamente, en lugar de copiar el mensaje, lo que supone un coste de
<math>O(n)</math>, se le devuelve al receptor una dirección de
memoria en la que se encuentra el mensaje.
Si se emplea junto a la denominación directa, el sistema operativo le
devuelve al receptor un puntero a la dirección en la que se encuentra el
mensaje. Si el mensaje está en el espacio del emisor, son necesarios
mecanismos explícitos de compartición de memoria entre procesos, ya
que dos procesos cualquiera no comparten memoria.
Si se emplea junto a la denominación indirecta, el emisor crea un
mensaje en el espacio del sistema operativo y se le ofrece un puntero al
receptor
9. Transmisión por copia en caso de escritura (COW)
Este método permite que los procesos emisor y receptor tengan
acceso a la zona de memoria del mensaje de forma controlada. La
zona puede pertenecer a uno de los procesos, o al SO, y se accede a
ella a través de una ventana en el espacio de direcciones que
inicialmente sólo permite consultar la información.
Cuando uno de los procesos intenta modificar el contenido del
mensaje, se detecta esta escritura gracias al mecanismo de
protección de la memoria. Entonces, el SO hace una copia para uno
de ellos, actualiza las referencias, y deja que ambos procesos
continúen.
Se mantiene un único espacio mientras sea posible.
10. Formas de comunicación
Comportamiento del emisor, send()
Síncrona: el proceso emisor que realiza el send() queda bloqueado
hasta que el receptor llama a recv() y el proceso bloqueado pasa a
estado preparado.
Asíncrona: suponemos una estructura de datos con capacidad de
almacenamiento limitada, dependiente del proceso destinatario o
en el buzón del SO. Al ser enviados, los mensajes irán encolándose
para que el proceso receptor pueda gestionarlos cuando pueda.
Comportamiento del receptor, recv()
Bloqueante: una llamada a recv() sin mensajes a procesar pasa el
proceso llamante a estado bloqueado. Un send() de otro proceso
que añada un mensaje a la cola del proceso bloqueado hace que
éste pase a estado preparado.
No bloqueante: una llamada a recv() sin mensajes a procesar
devuelve un mensaje de error, pero la ejecución del proceso
llamante continúa. Entendemos por proceso llamante a aquel que
hace uso de las llamadas send() y recv().
11. Formato de los mensajes
Fijo
Los procesos acuerdan emplear un formato fijo para sus mensajes.
Mixto
Los procesos acuerdan emplear mensaje con partes cuyo formato es
fijo, como por ejemplo una cabecera inicial, seguido de partes de
tamaño variable.
Mensajería a través de la red
Unicidad del destinatario
Fiabilidad en la transmisión
Formato de los datos
(http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/Data/endian
.html): Enviar un entero a través de la red puede ser un problema
debido a la forma en el que se representan los datos en la memoria
dependiente de la arquitectura.
12. Comunicación entre procesos:
Hay dos formas en que se puede comunicar los procesos, los cuales
son:
Por medio de un esquema de comunicación por memoria compartida
(Buffer)
Por medio de un mecanismo de comunicación entre procesos (IPC,
Interprocess comunication).
La IPC ofrece un mecanismo que permite a los procesos
comunicarse y sincronizar sus acciones. La mejor forma de proveer
la comunicación entre procesos es mediante un sistema de mensajes.
La función de un sistema de mensaje es permitir a los procesos
comunicarse entre sí sin tener que recurrir a variables compartidas.
Message-queuing system API:
put: añadir un mensaje a una cola. get: bloquear hasta que la cola no esté
vacía, luego quitar el primer elemento. poll: verificar si hay mensaje,
quitar el primero. Nunca se bloquea. notify: instalar en la cola un
dispositivo que avisará cuando un nuevo mensaje se inserte en la cola.
13. Comunicación orientada a mensajes
Las comunicaciones RPC se basan en la idea que el receptor está
operativo para poder invocar una cierta función, no podemos
suponer que el receptor siempre estará operativo y esperando a
comunicarse. La solución es definir la comunicación en término de
paso de mensajes.
Mensajes momentáneos vs. mensajes persistentes
Momentáneos: no soportan el envío de mensajes persistentes.
(1) Sockets, (2) Message-passing interface (MPI).
Sockets Berkeley
Sistema fuertemente acoplado a las redes TCP/IP
14. Sockets API:
socket: crea una nueva comunicación.
bind: añade la dirección local al socket.
listen: queda en espera de conexiones.
accept: queda bloqueado hasta la llegada de un pedido de
conexión.
connect: pedido de establecimiento de conexión.
send: enviar datos por la conexión.
receive: recibir datos por la conexión.
close: desvincula el socket la dirección local.
15. Message-passing interface (MPI)
Diseñado para aplicaciones paralelas crea un nivel de abstracción
más alto que el provisto por sockets. Provee una interface con
primitivas más avanzadas. Por el contrario cuenta con una gran
cantidad de implementaciones (librería y protocolos) propietarias lo
que genera la necesidad de una interface standard.
MPI API:
MPI_bsend: vincula la salida de mensajes con el buffer de salida
local.
MPI_send: envía un mensaje y espera hasta que es copiado al buffer.
MPI_ssend: envía un mensae y espera hasta que el receptor inicie.
MPI_sendrecv: envía un mensaje y espera respuesta.
MPI_isend: pasa la referencia de un mensaje y continúa.
MPI_issend: para la referencia de un mensaje y espera hasta que el
receptor inicie.
MPI_recv: recibe un mensaje; se bloquea en el caso de no haberlo.
MPI_irecv: verifica si hay mensajes entrantes; no se bloquea.
16. Persistentes: el mensaje se encola y se entrega cuando se pide. (1)
Message-oriented middleware (MOM)
Implementaciones
Hay un número de APIs que pueden ser usadas por IPC. Un
número de plataformas independientes de APIs incluidas las
siguientes:
Tuberías Anónimas y con nombre
Common Object Request Broker Architecture (CORBA)
Distributed Computing Environment (DCE)
Message Bus (MBUS) (especificado en RFC 3259)
ONC RPC
Sockets
XML XML-RPC or SOAP
ZeroC's Internet Communications Engine (ICE)