Post on 24-Apr-2020
Tema 3Comunicación y sincronización entre procesos
F. García-Carballeira, Mª. Soledad Escolar,
Luis Miguel Sánchez, Fco. Javier García
Sistemas Distribuidos
Grado en Ingeniería Informática
Universidad Carlos III de Madrid
Contenido
� Repaso de los conceptos de proceso y threads
� Concurrencia
� Mecanismos de comunicación
� Mecanismos de sincronización
� Llamadas al sistema de POSIX
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
2
� Llamadas al sistema de POSIX � para comunicación y sincronización de procesos
� Paso de mensajes
Bibliografía
Sistemas Operativos
2ª edición.
Por Jesús Carretero,
Prácticas de Sistemas Operativos: de la base al diseño
� Bibliografía básica:
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
3
Por Jesús Carretero, Félix García, Pedro de Miguel y Fernando Pérez
Mc. Graw-Hill
Por Jesús Carretero, Félix García, Pedro de Miguel y Fernando Pérez
Mc. Graw-Hill
Sistema Distribuido
� Sistema formado por recursos de computación (hardware y software) físicamente distribuidos e interconectados a través de una red, que comunican mediante paso de mensajes y cooperan para realizar una determinada tarea
La espina dorsal de los sistemas distribuidos son
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
4
Red
sistemas distribuidos son los mecanismos de comunicación entre procesos (IPC)
Conceptos previos
� Un programa es un conjunto de instrucciones
� Un proceso es un programa en ejecución
� Una red de computadores es un conjunto de computadores conectados por una red de interconexión
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
5
� Un sistema distribuido es un conjunto de computadores (sin memoria ni reloj común) conectados por una red
� Aplicaciones distribuidas: conjunto de procesos que ejecutan en uno o más computadores que colaboran y comunican intercambiando mensajes
� Un protocolo es un conjunto de reglas e instrucciones que gobiernan la comunicación en un sistema distribuido, es decir, el intercambio y formato de los mensajes
� Gestión de los recursos del computador� Ejecución de servicios para los programas en ejecución� Ejecución de los mandatos de los usuarios
Sistema Operativo
UsuariosAPI
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
6
Núcleo
Servicios
Procesos de usuario ShellSistemaoperativo
API
Hardware
@Fuente: Jesús Carretero, Félix García, Pedro de Miguel y Fernando Pérez. Mc Graw Hill
Componentes del Sistemas Operativo
Programas de usuario
Usuarios
Shell 1 Shell 2
Objetivo Tema 2
Objetivo Tema 2
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
7
Núcleo
Interfaz de llamadas al SOSistemaoperativo
Hardware
Gestión deprocesos
Gestión dememoria
Gestión de la E/S
Comunicac.y
sincroniz.
Seguridad y
protección
Gestión de archivos y directorios
@Fuente: Jesús Carretero, Félix García, Pedro de Miguel y Fernando Pérez. Mc Graw Hill
� Definición
� Programa en ejecución
� Unidad de procesamiento gestionada por el SO
� Para que un programa pueda ser ejecutado ha de residir en memoria principal
� Árbol de procesos
Proceso
Proc. Inic.
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
8
� Árbol de procesos� Relación de jerarquía
Inicio Inicio
ShellShell
Editor
Dem. Impr. Dem. Com..
Proceso A
Proceso B Proceso D Proceso C
Proceso E Proceso F
InicioInicio
@Fuente: Jesús Carretero, Félix García, Pedro de Miguel y Fernando Pérez. Mc Graw Hill
Información de los procesos
� El sistema operativo mantiene un conjunto de estructuras de información que permiten identificar y gestionar los procesos
Mapa de memoria del Proceso A
Mapa de memoria
Registrosespeciales
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
9
Mapa deMemoria
Tablas SOPC
SP
Estado
Mapa de memoria del Proceso B
Mapa de memoria del Proceso C
Registrosgenerales
Tablas del sistema operativo
Tabla de procesos
- Tabla de memoria- Tabla de E/S- Tabla de ficheros
BCP Proceso BBCP Proceso A BCP Proceso C- - Identificación- Control
Estado (registros)- - Identificación- Control
Estado (registros) - - Identificación- Control
Estado (registros)
@Fuente: Jesús Carretero, Félix García, Pedro de Miguel y Fernando Pérez. Mc Graw Hill
Proceso monothread o multithread
� Un proceso ligero, hilo o thread es un programa en ejecución (flujo de ejecución) que comparte la imagen de memoria (y otras informaciones) con otros procesos ligeros
� Dependiendo del número de procesos que puedan ejecutar simultáneamente, un SO es monotarea o multitarea
� Un proceso ligero puede contener un solo flujo de ejecución (monothread) o más (multithread)
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
10
o más (multithread)
� Por ejemplo, en el lenguaje C el hilo de ejecución primario se corresponde con la función principal main
Proceso
Procesos ligeros@Fuente: Jesús Carretero, Félix García, Pedro de Miguel y Fernando Pérez. Mc Graw Hill
Información propia/compartida
� Por thread (información propia)� Contador de programa, Registros
� Pila� Estado (ejecutando, listo o bloqueado)
� Por proceso (información compartida)
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
11
Por proceso (información compartida)� Espacio de memoria� Variables globales
� Ficheros abiertos
� Procesos hijos� Temporizadores
� Señales y semáforos
� Contabilidad
Estructura de un proceso con threads
Recursos (ficheros, ...)
Datos
CódigoProceso
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
12
Hilo 1Registros
Pila
Entorno del proceso
Hilo nRegistros
Pila
@Fuente: Jesús Carretero, Félix García, Pedro de Miguel y Fernando Pérez. Mc Graw Hill
Mapa de memoria de un proceso con threads
Mapa de memoriaCódigo
Fichero ejecutable
Fichero
Datos con valor inicial
Datos sin valor inicial
Heap
Fichero proyectado F
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
13
Bibliotecas Swap
Pila del thread n
Zona de memoria compartida
Pila de thread 1
Código biblioteca dinámica B
@Fuente: Jesús Carretero, Félix García, Pedro de Miguel y Fernando Pérez. Mc Graw Hill
Estados del proceso ligero
� Como los procesos convencionales, un proceso ligero puede estar en varias situaciones o estados: ejecutando, listo o bloqueado� El estado del proceso será la combinación de los estados de sus
procesos ligeros.
ProcesoBloqueado por comunicación
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
14
Proceso
Procesos ligeros
ActivoBloqueado por acceso a disco
@Fuente: Jesús Carretero, Félix García, Pedro de Miguel y Fernando Pérez. Mc Graw Hill
Threads y paralelismo
� Los procesos ligeros permiten paralelizar una aplicación
� Un programa puede dividirse en procedimientos que pueden ejecutar de manera independiente mediante procesos ligeros� Los procesos ligeros pueden lanzar su ejecución de manera simultánea
� Diseño modular de la aplicación
� La base del paralelismo:
� Mantener algún proceso ligero siempre en estado de ejecución: “mientras que un
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
15
� Mantener algún proceso ligero siempre en estado de ejecución: “mientras que un proceso está bloqueado otro podría estar ejecutando”
main(){
…
function1 (args);
function2 (args);
…
}
Diseño secuencial
main(){
…
lanzar_thread (
function1(args));
lanzar_thread (
function2(args));
}
Diseño paralelo
Ejemplo: ejecución serie vs. paralela
Procedimiento 1
Esperaen E/S
P F
Procedimiento 1
Ejecuciónserie
Procedimiento 2
Esperaen E/S
P F
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
16
Procedimiento 2
Procedimiento 1
Ejecuciónparalela
Esperaen E/S
P F
ProcesamientoEsperaen E/S
P F
@Fuente: Jesús Carretero, Félix García, Pedro de Miguel y Fernando Pérez. Mc Graw Hill
Programación concurrente
� En SSOO multitarea pueden coexistir varios procesos activos a la vez� Multiprogramación con un único procesador
� Multiprocesador
� Multicomputadora
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
17
� En general,
para p procesadores y n procesos, la concurrencia es:� Aparente si n>p
� real si n<=p
Comunicación entre procesos
Procesode Usuario
Procesode Usuario
Procesode Usuario
Procesode Usuario
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
18
SO
Un computador Dos computadores
SO SO
@Fuente: Jesús Carretero, Félix García, Pedro de Miguel y Fernando Pérez. Mc Graw Hill
Servidores secuenciales
� Diseño secuencial de servidores
Petición/respuestaCliente
Recurso
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
19
servidorCliente
Cliente
Recurso
Servidores concurrentes con threads
� Los procesos concurrentes deben comunicar y sincronizarse
petición
Crea thread de servicio
servidorCliente
Recurso
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
20
respuesta
de servicio
Thread de servicio
Diseño concurrente
@Fuente: Jesús Carretero, Félix García, Pedro de Miguel y Fernando Pérez. Mc Graw Hill
� Distintas arquitecturas de SW para construir servidores paralelos:
� Un proceso distribuidor que acepta peticiones y las distribuye entre un pool de procesos ligeros
� Cada proceso ligero realiza las mismas tareas: aceptar peticiones, procesarlas y devolver su resultado
� Segmentación: cada trabajo se divide en una serie de fases, cada una de ellas se procesa por un proceso ligero especializado
Diseño de servidores mediante threads
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
21
Trabajador
Núcleo Sol
icitu
des
Núcleo Sol
icitu
des
E/SNúcleo
Distribuidor
Sol
icitu
des
E/S E/S
@Fuente: Jesús Carretero, Félix García, Pedro de Miguel y Fernando Pérez. Mc Graw Hill
Programación con procesos ligeros
� Servicios UNIX incluyen:� Operaciones de gestión
� Creación e identificación de procesos ligeros
� Atributos de un proceso ligero
� Planificación de procesos ligeros� Prioridades, políticas de planificación
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
22
� Prioridades, políticas de planificación
� Terminación de procesos ligeros
Creación e identificación de threads
� Crear un thread:int pthread_create (pthread_t* thread,
const pthread_attr_t* attr, void * (*funcion)(void *), void * arg);
donde:
thread Identificador del nuevo thread (se captura cuando se crea)
attr Atributos a aplicar al nuevo thread o NULL
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
23
attr Atributos a aplicar al nuevo thread o NULL
funcion Función a ejecutar por el thread que es creado
arg Puntero a el/los argumentos del thread
devuelve:
int 0 si éxito o -1 si error
� Obtener el identificador de un thread:pthread_t pthread_self (void);
Atributos de un proceso ligero
� Un hilo se crea con una serie de atributos por defecto
� Ejemplo: Por defecto, un hilo es joinable o No Independiente
� Es posible modificar los atributos por defecto del hilo:� Inicia un objeto atributo que se puede utilizar para crear nuevos procesos ligeros
int pthread_attr_init (pthread_attr_t *attr);
� Destruye un objeto de tipo atributo
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
24
� Destruye un objeto de tipo atributoint pthread_attr_destroy (pthread_attr_t *attr);
� Cambiar el estado de terminación (Joinable / Detached)
int pthread_attr_setdetachstate (pthread_attr_t *a, int detachstate);
Si detachstate es� PTHREAD_CREATE_DETACHED el proceso se crea independiente
� PTHREAD_CREATE_JOINABLE el proceso se crea no independiente
� Otras atributos: tamaño de pila, planificación, prioridad, etc.
Terminación de procesos ligeros
� Finaliza la ejecución del proceso ligero:int pthread_exit (void *value);
� Para procesos creados como NO independientes es además necesario:
int pthread_join ( pthread_t thid , void ** value );
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
25
int pthread_join ( pthread_t thid , void ** value );
� Espera la terminación del proceso con identificador thid
� Devuelve en el segundo argumento el valor pasado en pthread_exit.
� Sólo se puede esperar la terminación de procesos ligeros no independientes (PTHREAD_CREATE_JOINABLE)
Ejemplo: Jerarquía de threads
No independientep_create
p_create
p_create
Thread A
Thread D Thread C
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
26
p_joinp_exit
p_exit
p_exitThread B
Thread D Thread C
@Fuente: Jesús Carretero, Félix García, Pedro de Miguel y Fernando Pérez. Mc Graw Hill
Ejemplo I: creación y terminación #include <stdio.h> /* printf */
#include <pthread.h> /* Para threads… */
#define NUM_THREADS 10
int funcion(int *idThread){
printf(“Thread id = %d\ti=%d: ”, pthread_self (),*idThread);
pthread_exit (NULL);
}
int main () {
pthread_t arrayThread[NUM_THREADS]; /* Array de threads */
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
27
pthread_t arrayThread[NUM_THREADS]; /* Array de threads */
int i;
/* CREAR THREADS */
for(i=0;i<NUM_THREADS;i++){
if ( pthread_create (&arrayThread[i],NULL,(void *)funcion, &i)==-1)
printf(“Error al crear proceso ligero\n”);
}
/* ESPERAR TERMINACIÓN DE THREADS */
for(i=0;i<NUM_THREADS;i++)
pthread_join (arrayThread[i], NULL);
exit(0);
}
Ejemplo I: Cuestiones
� ¿Por qué se pasa el argumento 4 de pthread_create como una referencia?
� Identificar variables compartidas y secciones críticas
� ¿Tiene este programa problemas de concurrencia?
� Dar un ejemplo de ejecución incorrecta.
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
28
Ejemplo II: Modificar atributos#include <stdio.h> /* printf */
#include <pthread.h> /* Para threads… */
#define MAX_THREADS 10
void func(void) {
printf("Thread %d \n", pthread_self());pthread_exit (0);
}
main() {
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
29
main() {int j;pthread_attr_t attr;pthread_t thid[MAX_THREADS];
pthread_attr_init (&attr);pthread_attr_setdetachstate (&attr,PTHREAD_CREATE_DETACHED);
for(j = 0; j < MAX_THREADS; j ++)pthread_create (&thid[j], &attr, func, NULL);
sleep(5);
pthread_attr_destroy (&attr);
}
Concurrencia
� Modelos:� Multiprogramación en un único procesador
� Multiprocesador
� Multicomputador (proceso distribuido)
� Ventajas:
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
30
� Facilita la programación
� Acelera los cálculos
� Posibilita el uso interactivo a múltiples usuarios
� Mejor aprovechamiento de los recursos
Monoprocesador vs. Multiprocesador
Proceso A
Proceso B
Proceso C
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
31
Tiempo
Tiempo
Proceso B
Proceso A
Proceso C
Proceso D
CPU 1
CPU 2
Tipos de procesos concurrentes
� Tipos de procesos: � Independientes: su ejecución no requiere la ayuda o cooperación con
otros procesos
� Cooperantes: su ejecución requiere trabajar conjuntamente con otros procesos para realizar una actividad
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
32
� En ambos casos se produce una interacción entre procesos � Compiten por recursos
� Comparten recursos
Conceptos previos
� Una condición de carrera es el acceso concurrente a los recursos compartidos sin coordinación� Puede producir resultados diferentes a los esperados
� Una sección crítica (SC) es un fragmento de código en el que los distintos procesos pueden acceder y modificar recursos compartidos
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
33
� Una sección es atómica si se ejecuta por un thread completamente de manera indivisible, de principio a fin, sin que su ejecución se pueda interrumpir por ningún otro thread
� Tienen una semántica de éxito-o-fallo
Ejemplo I:
Servidor concurrente
Distribuidor
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
34
E/SNúcleo
Cache
Solicitudes
@Fuente: Jesús Carretero, Félix García, Pedro de Miguel y Fernando Pérez. Mc Graw Hill
Ejemplo II:
Acceso a una caché compartida
Update_block() Update_block()
threadprincipal
Petición 1 Petición 2
� Condición de carrera en la sentencia: Update_block
Update_block(bloque) {
b = Get_block();
copy(b, bloque);
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
35
Update_block() Update_block()
Cache
copy(b, bloque);
}
copy(b1, b2){
for (i=0; i<length;i++)
*b1++ = *b2++;
Acceso a una caché compartida
� Condición de carrera en la sentencia: Update_block
Update_block(bloque) {
b = Get_block();
copy(b, bloque);Update_block() Update_block()
threadprincipal
Petición 1 Petición 2
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
36
copy(b, bloque);
}
copy(b1, b2){
for (i=0; i<length;i++)
*b1++ = *b2++;
Operación no atómica
Update_block() Update_block()
Cache
El problema de la sección crítica� Sistema compuesto por n procesos
� Cada uno tiene un fragmento de código: sección crítica� Los procesos deben acceder a la SC con exclusividad
� Estructura general de cualquier mecanismo utilizado para resolver el problema de la sección crítica:
Entrada en la sección crítica
Código de la sección crítica
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
37
Código de la sección crítica
Salida de la sección crítica
� Requisitos que debe ofrecer cualquier solución para resolver el problema de la sección crítica:
� Exclusión mutua
� Progreso
� Espera limitada
Modelos de comunicación y
sincronización
� Modelo productor-consumidor
� Modelo de lectores-escritores
� Modelo de acceso a recursos limitados
� Modelo cliente-servidor
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
38
Modelo productor-consumidor
ProcesoProductor
ProcesoConsumidor
Flujo de
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
39
Mecanismo de comunicación
Flujo de datos
@Fuente: Jesús Carretero, Félix García, Pedro de Miguel y Fernando Pérez. Mc Graw Hill
Modelo de lectores-escritores
EscritorLector Lector Escritor Lector
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
40
Recurso
@Fuente: Jesús Carretero, Félix García, Pedro de Miguel y Fernando Pérez. Mc Graw Hill
� Ejemplo: problema de los filósofos comensales
Modelo de acceso a recursos limitados
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
41
Modelo cliente-servidor
Procesocliente
Petición
Procesoservidor
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
42
Procesocliente
S.O.Respuesta
Procesoservidor
Comunicación cliente-servidor
� Muy utilizada en entornos distribuidos (más del 90% de los sistemas distribuidos utilizan la arquitectura cliente-servidor)
cliente
petcición
servidor
Máquina A Máquina B
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
43
� Protocolo típico: petición-respuesta
NÚCLEO
cliente
respuesta
servidor
NÚCLEO
RED@Fuente: Jesús Carretero, Félix García, Pedro de Miguel y Fernando Pérez. Mc Graw Hill
Mecanismos de comunicación
� Ficheros
� Tuberías (pipes, FIFOS)
� Variables en memoria compartida
� Paso de mensajes
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
44
Comunicación mediante archivos
� Un archivo es un mecanismo que puede emplearse para comunicar procesos� Un proceso puede escribir datos y otro puede leerlos
Dato1
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
45
Dato1
Dato2
Dato3
…
Dato n
Fichero compartido
Proceso escritor
Proceso lector
� Una tubería (pipe) es un mecanismo de comunicación y sincronización� Comunicación: archivo compartido
� Sincronización: semántica bloqueante
� Puede verse como un pseudoarchivo identificado por dos descriptores, uno se usa para leer y el otro para escribir� Los servicios utilizados para lectura y escritura de pipes son los mismos que los
Comunicación mediante tuberías
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
46
� Los servicios utilizados para lectura y escritura de pipes son los mismos que los usados sobre ficheros
read
Tubería
Proceso usuario
Proceso usuario
Flujo de datos
writeSO
Ejemplo III:
Productor-consumidor con tuberías#include <stdio.h> /* printf */
#include <unistd.h>
struct elemento dato; /* dato a producir */
int fildes[2];
int main () {
if ( pipe (fildes)<0){
printf(“Error al crear la tubería );
exit (1);
}
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
47
}
if (fork() == 0){
for (;;){
<Producir dato>
write (fildes[1], (char*)&dato, sizeof (struct elemento));
}
}else{
for (;;){
read (fildes[0], (char*)&dato, sizeof (struct elemento));
<Consumir dato>
}
}
Mecanismos de sincronización
� Señales (asincronismo)
� Tuberías (pipes, FIFOs)
� Semáforos
� Mutex y variables condicionales
� Paso de mensajes
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
48
� Paso de mensajes
Semáforos
� Un semáforo [Dijkstra, 1965] es un mecanismo de sincronización de procesos que ejecutan en la misma máquina
� Idea muy simple:� Un semáforo es un objeto con un valor entero inicialmente no negativo
� Dos operaciones atómicas� wait
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
49
� wait
� signal
� Operación wait
wait (s )
{
s = s - 1;
if (s < 0) {
<bloquear al proceso>
}
Operaciones sobre semáforos
� Operación signal
signal(s )
{
s = s + 1;
if (s <= 0)
<Desbloquear a un
proceso bloqueado por
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
}
}
proceso bloqueado por
la operacion wait >
}
}
Secciones críticas con semáforos
P0
Valor delsemáforo (s)
wait(s) wait(s)1
P1 P2
Ejecutando código de la sección crítica
wait (s); /* entrada en la seccion critica */
< seccion critica >
signal (s); /* salida de la seccion critica */
El semáforo debe tener valor inicial 1
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
51
wait(s)
signal(s)
signal(s)
signal(s)
wait(s)
desbloquea
desbloquea
wait(s)
1
0-1
-2
-1
0
Proceso bloqueado en el semáforo
s: valor entero asociado al semáforo
Estructura para projeger la SC:
wait ( s)
Código de la sección crítica
signal ( s)
Productor
Productor-consumidor con semáforos
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
52
Consumidor
@Fuente: Jesús Carretero, Félix García, Pedro de Miguel y Fernando Pérez. Mc Graw Hill
Ejemplo IV:
Productor-consumidor con semáforos
#define TAMAÑO_DEL_BUFFER 1024
Productor() {
int posicion = 0;
for(;;) {
Producir un dato;
Consumidor() {
int posición = 0;
for(;;) {
wait (elementos);
dato = buffer[posicion];
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
53
Producir un dato;
wait (huecos);
buffer[posicion] = dato;
posicion = (posicion + 1) % TAMAÑO_DEL_BUFFER;
signal (elementos);
}
}
dato = buffer[posicion]; posicion = (posicion + 1)
% TAMAÑO_DEL_BUFFER;
signal (huecos);
Consumir el dato extraído;
}
}
Ejemplo V:
Lectores-escritores con semáforos
Lector() {
wait (sem_lectores);
n_lectores = n_lectores + 1;
if (n_lectores == 1)
wait (sem_recurso);
signal (sem_lectores);
Escritor(){
wait (sem_recurso);
/*se puede modificar el recurso*/
signal (sem_recurso);
}
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
54
Consultar el recurso compartido
wait (sem_lectores);
n_lectores = n_lectores - 1;
if (n_lectores == 0)
signal (sem_recurso);
signal (sem_lectores);
}
}
Mutex
� Un mutex es un mecanismo de sincronización especialmente indicado para procesos ligeros
� Se emplean para tener exclusión mutua sobre SC y tener acceso exclusivo a los recursos compartidos
� Es un semáforo binario (valor inicial 1) con dos operaciones atómicas:
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
55
atómicas: � lock(m)
� Intenta bloquear el mutex.
� Si el mutex ya está bloqueado el proceso se suspende
� unlock(m)
� Desbloquear el mutex.
� Si existen procesos bloqueados en el mutex se desbloquea a uno
Secciones críticas con mutex
Thread A Thread Bthread ejecutando
lock (m) ; /* entrada en la seccion critica */
< seccion critica >
unlock (m) ; /* salida de la seccion critica */
� La operación unlock debe realizarla el proceso ligero que ejecutó lock
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
56
lock mutex
Seccióncrítica
lock mutex
unlock mutex obtiene mutex
thread bloqueado
Punto de sincronización
@Fuente: Jesús Carretero, Félix García, Pedro de Miguel y Fernando Pérez. Mc Graw Hill
Variables condicionales
� Una variable condicional es una variable de sincronización asociada a un mutex � Bloquea o desbloquea el proceso hasta que ocurra algún suceso
� Conveniente ejecutarlas entre las llamadas lock y unlock
Dos operaciones atómicas:
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
57
� Dos operaciones atómicas: � c_wait
� Bloquea al proceso ligero que la ejecuta y libera el mutex
� c_signal
� Desbloquea a uno o varios procesos suspendidos en la variable condicional
� El proceso que se despierta compite de nuevo por el mutex
Uso de mutex y variables condicionales
� Thread A lock ( m);
/* Código de la sección crítica */
while (condición == FALSE)
c_wait( c , m) ;
/* Resto la sección crítica */
unlock ( m); /* Salida de la SC */
� Thread Block ( m);
/* Código de la sección crítica */
/* Se modifica la condición */
condición = TRUE;
c_signal ( c);
/* Resto la sección crítica */
unlock ( m); /* Salida de la SC */
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
58
Thread BThread A
c_waitunlock mutex
Adquiere el mutex
Adquiere el mutex
Se compite por el mutex
locklock
unlock
Thread bloqueado esperando c_signal
Thread bloqueado esperando unlock
c_signal
@Fuente: Jesús Carretero, Félix García, Pedro de Miguel y Fernando Pérez. Mc Graw Hill
Uso de mutex y variables condicionales
� Thread A lock(mutex); /* acceso al recurso */
comprobar las estructuras de datos;
while (recurso ocupado)
wait(condition, mutex);
marcar el recurso como ocupado;
unlock(mutex);
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
59
unlock(mutex);
� Thread B lock(mutex); /* acceso al recurso */
marcar el recurso como libre;
signal(condition);
unlock(mutex);
� Importante utilizar while
Ejemplo VI: Productor-consumidor con
mutex y variables condicionales
Productor() {
int pos = 0;
for(;;) {
< Producir un dato >
lock (mutex);
/* acceder al buffer */
while (n_elementos == TAMAÑO_DEL_BUFFER)
c_wait (lleno, mutex);
Consumidor() {
int = 0;
for(;;) {
lock (mutex);
while (n_elementos == 0)c_wait (vacío, mutex);
dato = buffer[pos];
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
60
c_wait (lleno, mutex);
buffer[pos] = dato;
pos = (pos + 1) % TAMAÑO_DEL_BUFFER;
n_elementos ++;
if (n_elementos == 1)
c_signal (vacio);unlock (mutex);
}
}
dato = buffer[pos];
pos = (pos + 1) % TAMAÑO_DEL_BUFFER;
n_elementos --;
if (n_elementos == (TAMAÑO_DEL_BUFFER - 1));
c_signal (lleno);
unlock (mutex);
< Consumir el dato >
}
}
Servicios UNIX para mutex
� Inicializa un mutexint pthread_mutex_init (pthread_mutex_t *mutex,
pthread_mutexattr_t * attr);
� Destruye un mutexint pthread_mutex_destroy (pthread_mutex_t *mutex) ;
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
61
� Intenta obtener el mutex. Bloquea al proceso ligero si el mutex se encuentra adquirido por otro proceso ligeroint pthread_mutex_lock (pthread_mutex_t *mutex);
� Desbloquea el mutexint pthread_mutex_unlock (pthread_mutex_t *mutex);
Servicios UNIX para variables condicionales
(I)
� Inicializa una variable condicional
int pthread_cond_init (pthread_cond_t*cond,
pthread_condattr_t*attr);
� Destruye una variable condicionalint pthread_cond_destroy (pthread_cond_t *cond);
� Bloquea al proceso ligero y libera el mutex:
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
62
� Bloquea al proceso ligero y libera el mutex:� Suspende al proceso ligero hasta que otro proceso señaliza la variable
condicional cond .� Automáticamente se libera el mutex . Cuando se despierta el proceso ligero
vuelve a competir por el mutex .
int pthread_cond_wait (pthread_cond_t*cond,
pthread_mutex_t*mutex);
Servicios UNIX para variables condicionales
(II)
� Desbloquea el/los proceso(s) ligero(s) y libera el mutex
int pthread_cond_signal (pthread_cond_t *cond);
� Se reactivan uno o más de los procesos ligeros que están suspendidos en la variable condicional cond
� No tiene efecto si no hay ningún proceso ligero esperando (diferente a los semáforos)
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
63
semáforos)
int pthread_cond_broadcast (pthread_cond_t *cond);
� Todos los threads suspendidos en la variable condicional cond se reactivan
� No tiene efecto si no hay ningún proceso ligero esperando
Ejemplo VII:
Productor-consumidor con mutex (I)#define MAX_BUFFER 1024 /* tamanio del buffer */
#define DATOS_A_PRODUCIR 100000 /* datos a producir */
pthread_mutex_t mutex; /* mutex para controlar el acceso al buffer compartido */
pthread_cond_t no_lleno; /* controla el llenado del buffer */
pthread_cond_t no_vacio; /* controla el vaciado del buffer */
int n_elementos; /* numero de elementos en el buffer */
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
64
int buffer[MAX_BUFFER]; /* buffer comun */
int main(int argc, char *argv[]){
pthread_t th1, th2;
pthread_mutex_init (&mutex, NULL);
pthread_cond_init (&no_lleno, NULL);
pthread_cond_init (&no_vacio, NULL);
Ejemplo VII:
Productor-consumidor con mutex (II)pthread_create (&th1, NULL, Productor, NULL);
pthread_create (&th2, NULL, Consumidor, NULL);
pthread_join (th1, NULL);
pthread_join (th2, NULL);
pthread_mutex_destroy (&mutex);
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
65
pthread_cond_destroy (&no_lleno);
pthread_cond_destroy (&no_vacio);
return 0;
}
Ejemplo VII:
Productor-consumidor con mutex (III)void Productor(void) {
int dato, i ,pos = 0;
for(i=0; i<DATOS_A_PRODUCIR; i++ ) {dato = i; /* producir dato */pthread_mutex_lock (&mutex); /* acceder al buffer */
while (n_elementos == MAX_BUFFER)/* si buffer lleno */pthread_cond_wait (&lleno, &mutex); /* se bloquea*/
buffer[pos] = i;
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
66
buffer[pos] = i;
pos = (pos + 1) % MAX_BUFFER;n_elementos = n_elementos + 1;
if (n_elementos == 1)pthread_cond_signal (&vacio); /* buffer no vacío*/
pthread_mutex_unlock (&mutex);}pthread_exit(0 );
}
Ejemplo VII:
Productor-consumidor con mutex (IV)void Consumidor(void) {
int dato, i ,pos = 0;
for(i=0; i<DATOS_A_PRODUCIR; i++ ) {pthread_mutex_lock (&mutex); /* acceder al buffer */
while (n_elementos == 0) /* si buffer vacío */pthread_cond_wait (&vacio, &mutex); /* se bloquea */
dato = buffer[pos];
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
67
pos = (pos + 1) % MAX_BUFFER;n_elementos = n_elementos - 1 ;
if (n_elementos == MAX_BUFFER - 1);pthread_cond_signal (&lleno);/* buffer no lleno */
pthread_mutex_unlock (&mutex);
printf(“Consume %d \n”, dato); /* consume dato */}pthread_exit (0);
}
Contenido
� Paso de mensajes
� Colas de mensajes
� Llamadas al sistema de POSIX para comunicación y sincronización de procesos usando colas de mensajes
� Comunicación de grupos
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
68
� Comunicación de grupos
� Mecanismo de comunicación y sincronización de procesos que ejecutan en distintas máquinas
� En este tipo de comunicación, los procesos intercambian mensajes
� Entre los procesos que comunican debe existir un enlace de comunicación
Paso de mensajes:
conceptos básicos
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
69
comunicación
� Dos primitivas básicas:
� send (destino, mensaje)
� receive(origen, mensaje)
Modelo de comunicación
Proceso emisor
Proceso receptor
mensaje
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
70
� Emisor: Receptor:
send(destino, mensaje) receive(origen, mensaje)
emisor receptor
Paso de mensajes: conceptos básicos
Computador A Computador B
Procesode Usuario
mensaje1 dato
Procesode Usuario
mensaje2
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
71
SO SO
Proceso de comunicación
Computador A Computador B
Procesode Usuario
mensaje1 dato
Procesode Usuario
mensaje2
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
72
(mensaje1)
SO SO
Proceso de comunicación
Computador A Computador B
Procesode Usuario
mensaje1 dato
Procesode Usuario
mensaje2
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
73
(mensaje1)
dato
SO SO
Proceso de comunicación
Computador A Computador B
Procesode Usuario
mensaje1 dato
Procesode Usuario
mensaje2
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
74
(mensaje1)
dato
SO SO
dato
Proceso de comunicación
Computador A Computador B
Procesode Usuario
mensaje1 dato
Procesode Usuario
mensaje2
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
75
(mensaje1)
dato
SO
dato
SO
dato
Proceso de comunicación
Computador A Computador B
Procesode Usuario
mensaje1 dato
Procesode Usuario
mensaje2
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
76
(mensaje1)
dato
SO
(mensaje2)
dato
SO
dato
Proceso de comunicación
Computador A Computador B
Procesode Usuario
mensaje1 dato dato
Procesode Usuario
mensaje2
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
77
(mensaje1)
dato
SO
(mensaje2)
dato
SO
dato
Paso de mensajes:
cuestiones de diseño� Tamaño del mensaje
� Longitud fija o variable
� Flujo de datos
� Bidireccional, unidireccional
� Nombrado
� Comunicación directa
� send(P, m): envía un mensaje m al proceso P
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
78
� receive(Q, m): recibe un mensaje del proceso Q
� receive (ANY, m): recibe un mensaje de cualquiera
� Comunicación indirecta
� Colas de mensajes o puertos
� Sincronización
� Almacenamiento (buffering)
� Capacidad o no de almacenamiento del enlace de comunicaciones
� Fiabilidad
� Representación de datos, aplanamiento
� Nombrado� Comunicación indirecta: los datos se envían a estructuras intermedias
� Puertos: se asocian a un proceso (un único receptor)
� Ejemplo: sockets
� Colas de mensajes: múltiples emisores y receptores
� Ejemplo: Colas de mensajes POSIX
Paso de mensajes: cuestiones de diseño
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
79
Comunicación con puertosComunicación con colas de mensajes
Proceso cliente Proceso clientesend
mensaje
receive
Cola de mensajes
Proceso cliente Proceso cliente
mensaje
Puertosend
@Fuente: Jesús Carretero, Félix García, Pedro de Miguel y Fernando Pérez. Mc Graw Hill
� Sincronización
� Síncrona (bloqueante)
� Asíncrona (no bloqueante)
Paso de mensajes: cuestiones de diseño
Proceso A
Ava
nza
la e
jecu
ción
Proceso B
Proceso BComunicación síncrona
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
80
enviar
EsperaEsperarecibir enviar
recibir
El proceso A espera al B
Ava
nza
la e
jecu
ción
El proceso B espera al A
Proceso AProceso B
@Fuente: Jesús Carretero, Félix García, Pedro de Miguel y Fernando Pérez. Mc Graw Hill
Paso de mensajes: cuestiones de diseño
� El almacenamiento hace referencia a la capacidad del enlace de comunicaciones:� Sin almacenamiento:
� Comunicación entre los procesos emisor y receptor debe ser síncrona
� Con almacenamiento: las estructuras intermedias (colas o
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
81
� Con almacenamiento: las estructuras intermedias (colas o puertos) tienen un cierto tamaño para almacenar mensajes� Si la cola no está llena, el emisor al enviar un mensaje lo inserta en ella
y continúa su ejecución
� Si la cola está llena el emisor se bloquea
Colas de mensajes UNIX
� Implementación de paso de mensajes en UNIX
� Mecanismo de comunicación y sincronización
� Nombrado indirecto
� Asignan a las colas nombres de ficheros� Sólo pueden utilizar colas de mensajes procesos que comparten un
mismo sistema de ficheros
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
82
mismo sistema de ficheros
� Tamaño del mensaje variable
� Flujo de datos bidireccional
� Sincronización:� Envío asíncrono
� Recepción síncrona o asíncrona
� Los mensajes se pueden etiquetar con prioridades
Llamadas al sistema de POSIX para
gestión de colas de mensajes
� Crear y abrir una cola de mensajes
� Cerrar una cola de mensajes
� Borrar una cola de mensajes
� Modificar los atributos
� Enviar
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
83
� Enviar
� Recibir
Crear y abrir una cola de mensajes (I)
� Crear una cola de mensajes con nombre y atributosmqd_t mq_open(char *name, int flag, mode_t mode,
struct mq_attr *attr)
� El primer argumento especifica el nombre de la cola� Sigue la convención de nombrado de archivos
� man 7 mq_overview
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
84
� man 7 mq_overview
� El segundo argumento especifica los flags de la cola (definidos en fnctl.h):O_CREAT Crea una cola si no existe
O_RDONLY Crea una cola para lectura
O_WRONLY Crea una cola para escritura
O_RDWR Crea una cola para lectura y escritura
O_NONBLOCK Envío y recepción no bloqueante
Crear y abrir una cola de mensajes (II)
� El tercer argumento son los permisos de acceso a la cola (definido en sys/stat.h):� Permisos de lectura, escritura y ejecución
� El cuarto argumento especifica los atributos de la cola. Se usa la estructura attr, que entre otros campos define:
mq_maxmsg Número máximo de mensajes
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
85
mq_maxmsg Número máximo de mensajes
mq_msgsize Tamaño del mensaje
� Si no se especifica se toman los atributos por defecto
� La llamada mq_open devuelve un descriptor de cola o -1 si error
Cerrar y borrar una cola de mensajes
� Cerrar una cola de mensajesint mq_close (mqd_t mqdes)
� Borrar una cola de mensajes� Después de cerrar la cola de mensajes
int mq_unlink (char *name)
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
86
Ejemplo I: Crear una cola de mensajes#include <printf.h> /* printf */
#include <fcntl.h> /* flags */
#include <sys/stat.h> /* modes */
#include <mqueue.h>
#define NUM_MENSAJES 50
int main () {
mqd_t mqd; /* Descriptor de la cola */
struct mq_attr atributos; /* Atributos */
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
87
atributos. mq_maxmsg = NUM_MENSAJES;
atributos. mq_msgsize = sizeof(int);
if ((mqd= mq_open(“/almacen.txt”, O_CREAT|O_WRONLY, 0777, &atributos))==-1){
printf(“Error mq_open\n”);
exit(-1);
}
// Escribir en la cola
mq_close (mqd);
mq_unlink (“/almacen.txt”);
}
Ejemplo II: Compilar
� Es necesario enlazar la librería librtgcc filename.c –lrt –o executable
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
88
Gestión de los atributos
� Modificar los atributos de una colaint mq_setattr (mqd_t mqdes, struct mq_attr *qstat,
struct mq_attr *oldmqstat)
� Permite cambiar los atributos de una cola de mensajes
� Los nuevos atributos se pasan en qstat
� Si oldmqstat es distinto de NULL se almacenarán en él los antiguos atributos
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
89
� Obtener los atributos de una colaint mq_getattr (mqd_t mqdes, struct mq_attr *qstat)
� Devuelve los atributos de una cola de mensajes
Ejemplo III: Recuperar los atributos#include <printf.h> /* printf */
#include <fcntl.h> /* flags */
#include <sys/stat.h> /* modes */
#include <mqueue.h>
int main () {
mqd_t mqd; /* Descriptor de la cola */
struct mq_attr atributos; /* Atributos */
if ((mqd= mq_open(“/almacen.txt”, O_CREAT|O_WRONLY, 0777, &atributos))==-1){
printf(“Error mq_open \ n”);
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
90
printf(“Error mq_open \ n”);
exit(-1);
}
if ( mq_getattr (mqd, &atributos) == -1)
printf(“Error mq_getattr\n”);
exit(-1);
}
printf(“Numero maximo de mensajes en la cola: %d\n”, atributos .mq_maxmsg);
printf(“Longitud máxima del mensaje en la cola: %d\n”, atributos .mq_msgsize );
printf(“Numero de mensajes actualmente en la cola: %d\n”, atributos .curmsgs );
exit(0);
}
Comunicación y sincronización
� Las colas de mensajes ofrecen un mecanismo de comunicación y sincronización:� Comunicación:
� El nombre de la cola permite compartir ésta para que múltiples procesos puedan enviar y recibir datos
� Sincronización
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
91
� Sincronización
� Semántica bloqueante
� No bloqueante (O_NONBLOCK)
Servicios UNIX para enviar mensajes
� Enviar un mensaje a una colaint mq_send(mqd_t mqdes, char *msg, size_t len,int prio)
� El mensaje msg de longitud len se envía a la cola de mensajes mqdes con prioridad prio
� Argumentos de entrada
mqdes Descriptor de la cola
msg Buffer que contiene el mensaje a enviar
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
92
msg Buffer que contiene el mensaje a enviar
len Longitud del mensaje a enviar
prio Prioridad del mensaje. Los mensajes se insertan según su prioridad (0..MAX)
� Si la cola está llena el envío puede ser bloqueante o no (depende de O_NONBLOCK)� Si es O_NONBLOCK y la cola está llena el proceso no se bloquea pero devuelve -1 (error)
� Sino, devuelve el número de bytes enviados a la cola
Servicios UNIX para recibir mensajes
� Recibir un mensaje desde una colaint mq_receive (mqd_t mqdes, char *msg,
size_t len, int *prio)
� Recibe el mensaje msg con mayor prioridad en la cola (prio) de longitud len de la cola de mensajes mqdes
� Argumentos de entrada
mqdes Descriptor de la cola
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
93
mqdes Descriptor de la cola
msg Buffer que contiene el mensaje a recibir
len Longitud del mensaje a recibir
prio Prioridad del mensaje.
� Si la cola está vacía la recepción puede ser bloqueante o no (depende de O_NONBLOCK)� Si es O_NONBLOCK y la cola está vacía el proceso no se bloquea pero devuelve -1 (error)
� Sino, devuelve el número de bytes leidos de la cola
Relación entre descriptores y colas
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
94
@Fuente: Michael Kerrisk. The Linux Programing Interface.
Productor-consumidor con paso de
mensajesProductor () {
for(;;) {
<Producir dato>
send (Consumidor, dato);
} /* end for */
}
Consumidor () {
for(;;) {
receive (Productor, dato);
<Consumir dato>
} /* end for */
}
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Ejemplo III: Productor-consumidor con colas de mensajes
#include <mqueue.h>
#include <stdio.h>
#define MAX_BUFFER 1024 /* tamaño del buffer */
#define DATOS_A_PRODUCIR 100000 /* datos a p roducir */
mqd_t almacen; /* cola de mensajes donde dejar los datos producidos y extraer los datos a consumir */
void main(void){
struct mq_attr attr;
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
96
struct mq_attr attr;
attr.mq_maxmsg = MAX_BUFFER;
attr.mq_msgsize = sizeof (int);
almacen = mq_open(“ALMACEN”, O_CREAT|O_WRONLY, 0700, &attr);
if (almacen == -1){
perror (“mq_open”);
exit(-1);
}
Productor ();
mq_close (almacen);
exit(0);
}
Ejemplo III: Productor-consumidor con colas de mensajes
Productor (void){
int dato;
int i;
for(i=0;i<DATOS_A_PRODUCIR;i++){
/* producir dato */
dato = i;
if ( mq_send(almacen, &dato, sizeof(int), 0)== -1){
perror(“mq_send”);
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
97
perror(“mq_send”);
mq_close (almacen);
exit(1);
}
} /* end for */
return;
} /* end productor */
Ejemplo III: Productor-consumidor con colas de mensajes
#include <mqueue.h>
#include <stdio.h>
#define MAX_BUFFER 1024 /* tamaño del buffer */
#define DATOS_A_PRODUCIR 100000 /* datos a p roducir */
mqd_t almacen; /* cola de mensajes donde dejar los datos producidos y extraer los datos a consumir */
void main(void){
struct mq_attr attr;
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
98
struct mq_attr attr;
almacen = mq_open(“ALMACEN”, O_RDONLY);
if (almacen == -1){
perror (“mq_open”);
exit(-1);
}
Consumidor ();
mq_close (almacen);
exit(0);
}
Ejemplo III: Productor-consumidor con colas de mensajes
Consumidor (void){
int dato;
int i;
for(i=0;i<DATOS_A_RECIBIR;i++){
/* recibir dato */
dato = i;
if ( mq_receive (almacen,
&dato, siezof(int), 0)== - 1){
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
99
&dato, siezof(int), 0)== - 1){
perror(“mq_send”);
mq_close (almacen);
exit(1);
}
/* Consumir el dato */
printf(“El dato consumido es: %d\n”, dato);
} /* end for */
return;
} /* end consumidor */
Ejemplo IV: Cadena de montaje� Se pretende diseñar e implementar una cadena de montaje usando colas de mensajes de
UNIX. La cadena de montaje está compuesta por tres procesos, cada uno especializado en una función. La comunicación entre cada par de procesos (es decir el proceso i y el proceso i+1) se realiza a través de una cola de mensajes de UNIX. En esta cadena de montaje, cada proceso realiza una función bien diferenciada: � El primer proceso lee un fichero f1 y escribe en la primera cola trozos del fichero de longitud máxima 4KB.
� El proceso intermedio i lee de la cola i-1 cada trozo del fichero y realiza una simple función de conversión, consistente en reemplazar las letras minúsculas por letras mayúsculas. Una vez realizada esta transformación, escribe el contenido en la cola i.
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
100
� El último proceso lee de la cola i-1 y lo vuelca al fichero f2.
Ejemplo IV: Cadena de montaje
� El programa principal acepta dos argumentos de entrada, correspondientes al nombre del fichero origen (f1) y destino (f2). Debe ejecutarse de la siguiente manera:
cadena_montaje <f1> <f2>
� Se pide:� Decisiones de diseño necesarias para la implementación del programa
cadena_montaje
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
101
cadena_montaje
� Código fuente en el lenguaje de programación C del programa cadena_montaje.c