Comunicación entre procesos I (Tuberias)

Anuncio
COMUNICACIÓN ENTRE PROCESOS
En un sistema multitarea o multiproceso es muchas veces necesario que existan mecanismos de
comunicación entre los distintos procesos del sistema o entre procesos / aplicaciones entre máquinas
distintas. Muchas aplicaciones actuales se realizan siguiendo un modelo cliente y servidor, lo que permite
distribuir la carga de cada programa en distintas máquinas, aumenta la seguridad y flexibilidad.
Parte cliente : Capturar los las datos, los muestra, solicitar las consultas, mantener el interfaz de usuario.
Parte Servidor : Almacena y valida los datos, realiza los cálculos complejos, contestar las respuestas
Esquema:
SERVIDOR
Inicializar
Abrir Canal de peticiones
MIENTRA(1)
Leer(Petición)
ElaborarRespuesta(Petición, resultado)
Enviar(resultado)
FIN-MIENTRAS
CLIENTE
Inicializar
Conectar con el Servidor
EnviarPetición (datos petición);
EsperarRespuesta (datos respuesta);
ProcesarRespuesta ( datos respuesta);
Los servidores pueden suele ser interactivos o concurrentes
-Interactivos: Realizan ellos mismo el tratamiento de la petición,-> Sólo pueden procesar una petición
cada vez
-Concurrentes: Crean nuevos procesos o mantienen activos una serie de ellos para tratar cada nueva
petición -> Pueden procesar varias peticiones cada vez
Cuando una aplicación está formada por muchos procesos que comparten una gran cantidad de
datos siendo preciso el menor tiempo de respuesta posible, el método ideal es utilizar múltiples hilos en
vez de proceso normales. Sin embargo esto tiene el inconveniente de obligar a que toda la aplicación se
ejecute sobre una misma máquina lo que reduce la flexibilidad. Habitualmente se utilizan métodos
mixtos la aplicación cliente - servidor se realiza en base a varios procesos cada uno de ellos con múltiples
hilos.
MECANISMOS DE COMUNICACIÓN
Internos (Entre procesos dentro de una misma máquina )
Básicos
•Señales ( Informan de sucesos pero no sirven para envían o reciben datos adicionales)
•Ficheros con bloqueos ( Relativamente lento -> acceso a disco ) ( Pseudo- Bases de Datos )
•Tuberías : Fifo internas (pipe) y fifos externas con nombre ( Memoria RAM, más rápida,
capacidad limitada 4 – 8 kb )
Mecanismos IPC de UNIX System V
•Semáforos ( Mecanísmo de sincronización )
•Colas de mensajes ( Intercambio ordenado de cantidades discretas de datos )
•Memoria compartida ( Acceso compartido a un mismo espacio de memoria)
Externos (Entre proceso de distintas máquinas conectadas mediante una red )
Comunicación basada en sockets
AF_UNIX ( Similar a la fifos con nombre pero bidireccionales)
AF_INET ( Mediante el uso del protocolo TCP/IP ) -> TCP o UDP
TUBERIAS O PIPES. FIFOS INTERNOS
Es el método más sencillo y antiguo de comunicación entre dos procesos donde la salida de un
programa es la entrada del otro (pipeline). Una Tuberia o pipe, es una estructura de datos interna que
ofrece el kernet, que pueden contener un conjunto limitado de datos ( 4 a 8 K), a la que se accede
mediante operaciones de lectura y escritura sobre dos descriptores, uno de abierto para lectura y otro para
escritura.
Se implementa un modelo productor Æ consumidor, más que cliente - servidor. Permite una
comunicación Simplex (unidireccional.)
Ejemplos:
$who | sort
$ps -ef | fgrep a01 | wc -l
¿Que es lo que ocurre cuando ejecutamos la orden who | sort?
•Se crea un pipe, tubería interna.
•Se redirecciona la salida estándar del proceso who al ( descriptor nº 1 ) al pipe
•Se redirecciona la entrada estándar del proceso sort (descriptor nº 0 ) al pipe
•Y se ejecutan cada programa independiente
Proceso
who
Proceso
sort
Tubería interna
Salida estándar
Entrada estándar
PREVIO: Concepto de redirección y llamada dup
int dup ( descriptor )
Duplicar un descriptor abierto: Abre un nuevo descriptor que señala al mismo fichero o i_nodo que el
indicado
Ej.fd = open(“datos.dat”,O_RDONLY);
nfd = dup(fd);
write(nfd, datos, nbytes ); // Tanto el descritor fd como nfd están señalando al mismo fichero.
Ej.- Redirección Numeración de los descriptores: 0 - stdin 1 - stdout 2 - stderr
Cada vez que se abre un descriptor se asigna el valor más bajo disponible.
Ejemplo sencillo de redirección:
fclose(stdout);
pf = fopen(“Salida.txt”,”w”);
printf(“ %s”,mensaje); fprintf(pf,”%s”,mensaje); // Escriben sobre el mismo fichero
system(“who”); /* La salida estándar (stdout) pasaría a ser el fichero Salida.txt por lo tanto el
comando who al escribir en la sálida estándar escribirá realmente sobre el fichero Salida.txt */
CREACIÓN DE UNA TUBERÍA
int pipe(int descf[2]); Parámetro una tabla con dos enteros.
descf[0] Está abierto para lectura
descf[1] Está abierto para escritura
DESCRIPCIÓN
pipe crea un par de descriptores de ficheros, que apuntan a un inodo de una tubería, La posición.
descf[0] es para lectura, descf[1] es para escritura. Cada proceso suele cerrar descriptor que no vaya a
utilizar antes de leer o escribir en el pipe.
Comportamiento de una tuberia (pipe):
•Comunicación Simplex. En una dirección.
•Tamaño de 4.096 . Si esta lleno el proceso escritor se espera, si está vacía el
proceso lector se espera
•Si se ha cerrado el extremo de escritura, el lector puede continuar leyendo mientras
haya datos hasta, la función read devuelve 0 byte indicando que está vacío.
•Si se ha cerrado el extremo de lectura, al intentar escribir fallará generándose la
señal SIGPIPE (Tubería Rota)
Ejemplos en la web:
1.- Programar el comando ps -ef | sort
2.- Lector que envía al comando sort
3.- Lector y escritor inverso (Misma pantalla )
La forma fácil: la función de librería POPEN
FILE *popen(const char *orden, const char *tipo);
int pclose(FILE *flujo);
DESCRIPCIÓN
La función popen() inicia un proceso creando una tubería, llamando a fork, para crear el proceso y
ejecutando el intérprete de comandos (shell). Puesto que una tubería es unidireccional por definición, el
argumento tipo sólo puede especificar lectura o escritura, pero no ambos; el flujo resultante es
respectivamente de lectura o escritura exclusiva.
Ejemplos en la web:
1. Lector que envía al comando sort popen
2. Muestra el contenido de una tabla en orden.
TUBERIAS CON NOMBRE (FIFO)
Inconveniente de las tuberías internas o pipe:
Los procesos deben ser parientes => mismo usuario, arrancarse casi a la vez, Un nuevo proceso
arrancado por un usuario no puede comunicarse con otro arrancado anteriormente.
Características de la FIFO ( Tuberías externas o con nombre )
Una tubería con nombre funciona como un pipe normal, pero tiene algunas diferencias notables:
•Las tuberías con nombre existen en el sistema de archivos como un archivo de dispositivo especial.
Con su propietario, grupo y permisos correspondientes (prw-rw-r--)
•Los procesos de diferentes padres pueden compartir datos mediante una tubería con nombre, si
poseen los permisos necesarios.
•Cuando se han realizados todas las operaciones de E/S la tubería con nombre no desaparecen sino
que permanece en el sistema de archivos para un uso posterior, aunque no almacena datos si no hay
ningún proceso con la tubería abierta.
Creación de una FIFO:
Por comando : mkfifo <nombre>
prw-r--r-- P indica pipe.
Por programa
int mknod(nombre, S_IFIFO | 0666, 0);
El valor 0666 corresponde con la mascara de permisos: rw-rw-rwUna FIFO se comporta como un fichero normal, pero sólo se puede abrir para leer o escribir, no se puede
añadir y ni podemos posicionarnos. Normalmente, la apertura de una FIFO se realiza de forma
sincronizada. En otras palabras, si se abre el FIFO para lectura, el proceso se quedará "bloqueado" hasta
que cualquier otro proceso lo abra para escritura. Este comportamiento funciona al revés también. Si esta
propiedad no nos interesa, se puede usar la opción O_ NONBLOCK o O_NDELAY en la llamada a
open () para desactivar la acción de bloqueo por omisión. En este caso la llamada nos devolverá –1 si no
hay nadie al otro lado.
Comportamiento de una tubería con nombre (FIFO)
• Las tuberías con nombre deberán tener como mínimo un lector y un escritor.
• Si un proceso trata de escribir en una tubería que no tiene lector, el núcleo enviará la señal
SIGPIPE que por omisión provoca la terminación del proceso.
• Si un proceso intenta leer de una tubería que no tiene escritor, el S.O. Devuelve cero bytes en
la llamada read indicando fin de fichero.
• Estos comportamientos se pueden modificar abriendo el FIPO de entrada y salida
• La tubería con nombre al igual que las pipes sólo permiten la comunicación unidireccional
Ej.$ mkfifo canal
$ cat canal &
Probar desde otro terminal
$ ls -l > canal
Ejemplos de un Modelo productor- consumidor:
Un proceso que envía y otro proceso que recibe: sobre una misma pipe llamada canal
1.- Abriendo y cerrando el pipe por cada mensaje: enviarfifo y recibirfifo
2.- Abriendo y cerrando al final: enviarfifo2 y recibirfifo2
Proceso
leerfifo
Proceso
enviarfifo
Fifo canal
Ejemplo del Modelo cliente – servidor:
Se utilizan dos fifos para permitir la comunicación en ambos direcciones. Una fifo para peticiones y y
otra para respuestas
Proceso
Cliente
Fifo frespuestas
Proceso
Servidor
Fifo fpeticiones
3.- Ejemplo de cliente y servidor utilizando dos FIFO fpeticiones y frespuestas
4.- Servidor Matemático basado en el ejemplo anterior.
5.- Servidor con Múltiples clientes -> FIFO de repuesta privada, la dirección de respuesta se indica en el
propio mensaje de petición. La fifo de respuesta se construye al partir del PID del proceso cliente.
Proceso
Cliente
Pid=9283
Proceso
Cliente
Frespuestas9283
frespuestas3440
Pid=3440
Fifo fpeticiones
Proceso
Servidor
Descargar