Los servicios de comunicación entre procesos son la base de los sistemas distribuidos al permitir que dos procesos colaboren para lograr una tarea
Hay dos mecanismos básicos de comunicación entre procesos
1- Comunicación entre procesos a nivel del sistema operativo (sin red)
Permiten la comunicación entre dos procesos en el mismo ordenador
Ejemplos: Colas de mensajes, semáforos, memoria compartida, etc.
No vamos a utilizarlos en este curso
2- Comunicación entre procesos a través de una red
Permiten la comunicación entre dos procesos que residan en la misma red
En este caso, la comunicación se produce a través del intercambio de mensajes entre un emisor y un receptor
El intercambio puede ser uno-a-uno (unicast – unidifusión) o uno-a-grupo (multicast – multidifusión)
IPC – Comunicación entre procesos
Cuando un ordenador tiene soporte de red, ofrece una API que proporciona los servicios de comunicaciones
Estas APIs tratan de proporcionar una interfaz abstracta al programador
Toda API debe proporcionar, al menos, cuatro tipos de operaciones al desarrollador
ENVIAR: Es una primitiva que invoca el proceso emisor con el propósito de transmitir datos a un proceso receptor. Esta primitiva debe permitir identificar al proceso receptor así como especificar los datos a transmitir
RECIBIR: Es una primitiva que invoca el proceso receptor con el objetivo de aceptar datos de un proceso emisor. Debe permitir identificar al proceso receptor así como especificar el área de memoria en la que se almacenará la información recibida
Inicio de la conexión: Para mecanismos de comunicación orientados a conexión, deben existir primitas que permitan que la conexión se establezca. Lo habitual es que existan dos de ellas:
ESPERAR-CONEXIÓN: Es una primitiva invocada por un proceso que está dispuesto a recibir la conexión de otro proceso de forma pasiva.
INICIAR-CONEXIÓN: Esta primitiva es invocada por un proceso que quiere iniciar una conexión de manera activa con otro proceso. Es necesario identificar al proceso remoto
DESCONECTAR: En comunicaciones orientadas a conexión, cualquiera de los dos extremos de una conexión establecida pueden liberarla invocando esta primitiva
Elementos básicos de una API de IPC para redes
Si observamos detenidamente la API básica que hemos definido vemos que
Para que un mensaje pueda transferirse realmente, necesitamos que
Toda llamada ENVIAR en un extremo, debe tener una llamada RECIBIR en el otro
Para que una conexión pueda establecerse realmente, necesitamos que
Toda llamada INICIAR-CONEXIÓN debe tener un ESPERAR-CONEXIÓN asociada
¿Cómo logran los procesos ponerse de acuerdo para coordinar sus llamadas?
Más aún …
¿Qué tenemos que hacer cuando en el código que desarrollamos para que los programas se coordinen al ejecutarse como procesos?
Sincronización de los procesos remotos
Proceso E
Proceso R
ENVIAR
RECIBIR?
Proceso E
Proceso R
INICIAR
ESPERAR?
Definición de Sincronizar:
“Hacer que coincidan en el tiempo dos o más fenómenos”
¿Cómo sincronizamos la ejecución de ENVIAR en un proceso con la ejecución de RECIBIR en el otro?
El mecanismo de sincronización más sencillo es el de utilizar comandos bloqueantes
Un comando bloqueante es aquel que bloquea al proceso que lo invoca hasta que se verifica una cierta condición, momento en el que el proceso para a estar Listo
Para el envío de un mensaje, el primer proceso que alcanza el comando ENVIAR/RECIBIR se bloquea hasta que el otro proceso “lo alcanza”
Para el establecimiento de una conexión, el proceso que invoca ESPERAR se bloquea hasta que otro proceso invoca INICIAR
Sincronización de los procesos remotos
Ejemplo de comunicación con comandos bloqueantes
…
int x = leerDato();
int y = leerOtroDato();
int z = x + y;
String resultado=“Suma=“+z;
enviar(procesoII, resultado);
…
…
llamarYoda();
sacarEspadaLaser();
matarSauron();
int z = recibir(procesoI)
pagarImpuestos(z);
…
ProgramaII
ProgramaI
(Gp:) Listo
(Gp:) Bloqueado
(Gp:) Ejecutando
(Gp:) Listo
(Gp:) Bloqueado
(Gp:) Ejecutando
Ejecutando
Ejemplo de comunicación con comandos bloqueantes
…
int x = leerDato();
int y = leerOtroDato();
int z = x + y;
String resultado=“Suma=“+z;
enviar(procesoII, resultado);
…
…
llamarYoda();
sacarEspadaLaser();
matarSauron();
int z = recibir(procesoI)
pagarImpuestos(z);
…
ProgramaII
ProgramaI
(Gp:) Listo
Bloqueado
Ejecutando
(Gp:) Listo
Bloqueado
Ejecutando
Ejemplo de comunicación con comandos bloqueantes
…
int x = leerDato();
int y = leerOtroDato();
int z = x + y;
String resultado=“Suma=“+z;
enviar(procesoII, resultado);
…
…
llamarYoda();
sacarEspadaLaser();
matarSauron();
int z = recibir(procesoI)
pagarImpuestos(z);
…
ProgramaII
ProgramaI
(Gp:) Listo
Bloqueado
Ejecutando
(Gp:) Listo
Bloqueado
Ejecutando
Ejemplo de comunicación con comandos bloqueantes
…
int x = leerDato();
int y = leerOtroDato();
int z = x + y;
String resultado=“Suma=“+z;
enviar(procesoII, resultado);
…
…
llamarYoda();
sacarEspadaLaser();
matarSauron();
int z = recibir(procesoI)
pagarImpuestos(z);
…
ProgramaII
ProgramaI
(Gp:) Listo
Bloqueado
Ejecutando
(Gp:) Listo
Bloqueado
Ejecutando
Ejemplo de comunicación con comandos bloqueantes
…
int x = leerDato();
int y = leerOtroDato();
int z = x + y;
String resultado=“Suma=“+z;
enviar(procesoII, resultado);
…
…
llamarYoda();
sacarEspadaLaser();
matarSauron();
int z = recibir(procesoI)
pagarImpuestos(z);
…
ProgramaII
ProgramaI
(Gp:) Listo
Bloqueado
Ejecutando
(Gp:) Listo
Bloqueado
Ejecutando
Ejemplo de comunicación con comandos bloqueantes
…
int x = leerDato();
int y = leerOtroDato();
int z = x + y;
String resultado=“Suma=“+z;
enviar(procesoII, resultado);
…
…
llamarYoda();
sacarEspadaLaser();
matarSauron();
int z = recibir(procesoI)
pagarImpuestos(z);
…
ProgramaII
ProgramaI
(Gp:) Listo
Bloqueado
Ejecutando
(Gp:) Listo
Bloqueado
Página siguiente |