Comunicación y sincronización de procesos



Documentos relacionados
Implementación de monitores POSIX

Concurrencia entre Procesos.

Concurrencia: deberes. Concurrencia: Exclusión Mutua y Sincronización. Concurrencia. Dificultades con la Concurrencia

Mensajes. Interbloqueo

Concurrencia: Exclusión mutua y Sincronización

CDI Exclusión mutua a nivel alto. conceptos

Concurrencia. Primitivas IPC con bloqueo

SISTEMAS OPERATIVOS AVANZADOS

PROGRAMACIÓN CONCURRENTE. Tema 5 Monitores

un programa concurrente

Tema 4. Gestión de entrada/salida

Tema 3. Monitores Programación Concurrente

Hilos, comunicación y competencia entre procesos. Dr. Alonso Ramírez Manzanares 2-Sep-2010

SIMM: TEORÍA DE LOS S.O. I.E.S. JUAN DE LA CIERVA CURSO 2007/2008

Sistemas Operativos. Características de la Multiprogramación. Interacción entre Procesos. Características de la Multiprogramación

Receta general para resolver problemas de sincronización con semáforos

1 (2 5 puntos) Responda con brevedad y precisión a las siguientes preguntas:

4. Programación Paralela

PROGRAMACION CONCURRENTE

Sistemas operativos. Comunicación y sincronización de procesos

Paso de mensajes. Lecturas: Burns & Wellings, Cap.??? Transparencias y apuntes de la asignatura. Filosofía cliente-servidor.

El problema de los Filósofos

Arquitectura de sistema de alta disponibilidad

PROGRAMACION CONCURRENTE

Sistemas Operativos Práctica 4

Sistemas Operativos Temas 4, 5 y 6. Jorge García Duque Despacho: B-202 Tutorías: Lunes 16:00-18:00 y Martes 16:00-20:00

RESUMEN DE CONCEPTOS BASICOS DE PROGRAMACION JAVA

Introducción a la programación orientada a objetos

PROGRAMACIÓN EN JAVA

Benemérita Universidad Autónoma del Estado de Puebla

Unidad 1: Conceptos generales de Sistemas Operativos.

PROGRAMACION CONCURRENTE Y DISTRIBUIDA. II.5 Sincronización basada en memoria compartida: Monitores

Estructuras de Sistemas Operativos

Sistemas de archivos distribuidos. Alvaro Ospina Sanjuan

Tema 3: Concurrencia de procesos

Práctica 2: El problema de la sección crítica

Tema 1: Introducción a los S.O. Ejercicios de Planificiación de Procesos

MONITORES EN JAVA. Antonio Tomeu Control de la Concurrencia en Java: API Estándar

Ingeniería Superior de Informática. Curso 3º. Sistemas Operativos. Examen Final. TEORÍA. 31 de Enero de 2005

SOLUCION EXAMEN junio 2006

Modulo 1 El lenguaje Java

Memoria compartida y semáforos r/w. La página del manual que podría servir para describir estas funciones es la siguiente:

Capítulo 1 Introducción a la Computación

Capítulo IV. INTERBLOQUEO E INANICIÓN

Contenido. Qué es el interbloqueo? Cómo prevenirlo? Cómo evitarlo? Cómo detectarlo? Interbloqueo. Cruce en un Puente. Qué es?

GENERACIÓN DE CÓDIGO

CAPÍTULO 8. Comunicación y sincronización basada en variables compartidas

Q-flow Patrones básicos de Workflow

Laboratorio 7 Motor de búsqueda web basado en el TAD Árbol Binario de Búsqueda GUIÓN DEL LABORATORIO

WINDOWS : TERMINAL SERVER

Examen escrito de Programación 1

7. Manejo de Archivos en C.

Introducción a las redes de computadores

Creación de Funciones de Conducción

Práctica GESTIÓN Y UTILIZACIÓN DE REDES LOCALES. Curso 2001/2002. TCP/IP: protocolo TCP

1. Descripción y objetivos

En cualquier caso, tampoco es demasiado importante el significado de la "B", si es que lo tiene, lo interesante realmente es el algoritmo.

Introducción a la Firma Electrónica en MIDAS

Herencia. 3.- Herencia. Declaración de una clase derivada en Delphi. Jerarquía de clases

GESTIÓN DOCUMENTAL PARA EL SISTEMA DE CALIDAD

ANEXOS. Algoritmo que genera un valor hash de algún dato, como una clave de. mensaje o de sesión. Con un buen algoritmo de hash, los cambios que se

Objetivos de la práctica: - Practicar uso de ficheros: abrir, cerrar y tratamiento de información contenida en el fichero.

El soporte del sistema operativo. Hace que un computador sea más fácil de usar. Permite que los recursos del computador se aprovechen mejor.

LABORATORIO DE RC: PRÁCTICA 4: IMPLEMENTACIÓN DE UN CLIENTE DE CORREO

18 y 19 Sistemas de Archivos Distribuidos y Tarea 05

Procesos. Bibliografía. Threads y procesos. Definiciones

Clases y Objetos. Informática II Ingeniería Electrónica

Proyecto Septiembre. Escuela Politécnica Superior Universidad Autónoma de Madrid 1

Java nos ofrece la clase Thread y la interfaz Runable que permiten que varios procesos estén funcionando de forma concurrente.

Programación Orientada a Objetos con Java

1. Equivalencia de herramientas. Implemente las primitivas de las regiones críticas condicionales con semáforos. (2pt).

Sistemas de Operación II

Unidad 1: Conceptos generales de Sistemas Operativos.

Sistemas Operativos. Curso 2016 Procesos

ASIGNACIÓN (PREROUTING) De las llamadas entrantes en función del número llamante y del número llamado

ARQUITECTURA DE DISTRIBUCIÓN DE DATOS

Escuela Politécnica Superior de Ingeniería Departamento de Ingeniería Informática

Unidad II: Administración de Procesos y del procesador

- Bases de Datos - - Diseño Físico - Luis D. García

CONCEPTOS BASICOS. Febrero 2003 Página - 1/10

8. Sentencia return y métodos

Mensajes. (versión preliminar)

Manual del Protocolo XML-RPC de Mensajería Negocios

Tema 1 Introducción. Arquitectura básica y Sistemas Operativos. Fundamentos de Informática

Parámetros con la ventana de selección de usuario, reglas, texto y descomposición (IVE)

Procesos. Planificación del Procesador.

/05/2009

2 Sea una unidad de disco duro de brazo móvil con las siguientes características:

Solución Examen Febrero 2006

PROGRAMACION CONCURRENTE. I.2 Recursos para la concurrencia.

Concurrencia en.net David Jesús Horat Flotats

Unidad didáctica: Funcionamiento de un parking. Actividad: Funcionamiento de un parking de vehículos con entrada y salida automática con:

Centro de Capacitación en Informática

A continuación se describen cuáles son los elementos principales de las tablas, cómo crear una y cómo modificarla.

Elementos requeridos para crearlos (ejemplo: el compilador)

PROGRAMACIÓN ORIENTADA A OBJETOS Master de Computación. II MODELOS y HERRAMIENTAS UML. II.2 UML: Modelado de casos de uso

PROCESO ADMINISTRACIÓN DE RECURSOS TECNOLÓGICOS SUBPROCESO ADMINISTRACIÓN DE CONTINGENCIAS

COPIAS DE SEGURIDAD AUTOMÁTICAS DE DIRECCIONES CALLEÇPAÑA

DISCOS RAID. Se considera que todos los discos físicos tienen la misma capacidad, y de no ser así, en el que sea mayor se desperdicia la diferencia.

SEGURIDAD Y PROTECCION DE FICHEROS

Transcripción:

Sistemas Operativos I Tema 4 Comunicación y sincronización de procesos Equipo de Sistemas Operativos DISCA / DSIC UPV Comunicación y sincronización de procesos Objetivos Presentar dos alternativas básicas para comunicación entre procesos Memoria común Mensajes Analizar las condiciones de carrera y estudiar el concepto de seriabilidad. Estudiar, en el caso de memoria común, el problema de la sección critica. Presentar los criterios de corrección al problema de la sección critica y sus posibles soluciones de una forma estructurada: Soluciones hardware Semáforos Realización de semáforos mediante soluciones hardware. Adquirir destreza en la resolución de problemas de sincronización a través de problemas clásicos (productores y consumidores, lectores y escritores, cinco filósofos, etc.) 2 1

Comunicación y sincronización de procesos Contenido Bibliografia 1.- Introducción 2.- Comunicación por memoria común 3.- El problema de la sección crítica 4.- Soluciones hardware 5.- Semáforos A. Silberschatz, J. Peterson, P. Galvin. Sistemas Operativos. Conceptos undamentales. 5ª ed. Capítulo 6. A. Tanenbaum. Modern Operating Systems. Capítulos 2,11 y 12 6.- Problemas clásicos de programación concurrente 7.- Construcciones lingüísticas 8.- Sincronización en POSIX 9.- Comunicación por mensajes 3 Comunicación y sincronización de procesos Contenido 1.- Introducción 2.- Comunicación por memoria común 3.- El problema de la sección crítica 4.- Soluciones hardware 5.- Semáforos 6.- Problemas clásicos de programación concurrente 7.- Construcciones lingüísticas 8.- Sincronización en POSIX 9.- Comunicación por mensajes 4 2

1.Introducción Existe la necesidad de comunicación entre procesos. Los procesos requieren con frecuencia comunicación entre ellos (ejemplo: tubos). La comunicación entre procesos puede seguir dos esquemas básicos: Comunicación por memoria común Comunicación por mensajes 5 1.Introducción Comunicación por memoria común La comunicación por memoria común se puede dar en los siguientes casos: Espacio de direcciones único: es el caso de los hilos de ejecución El s.o. crea una zona de memoria accesible a un grupo de procesos Problema de la sección crítica: en un sistema con procesos concurrentes que se comunican compartiendo datos comunes es necesario sincronizar el acceso (lectura, escritura) a los datos compartidos para asegurar la consistencia de los mismos. P1 Hilo 1 Hilo 2 Datos compartidos 6 3

1.Introducción Comunicación por mensajes La comunicación por mensajes se da normalmente en el siguiente caso: Espacio de direcciones independentes Sincronización en la comunicación por mensajes: Cuando dos procesos se comunican vía mensajes se necesitan mecanismos para que el proceso receptor espere (se suspenda hasta) a que el proceso emisor envíe el mensaje y éste esté disponible. No aparece el problema de la sección crítica. P1 P2 mensaje 7 Comunicación y sincronización de procesos Contenido 1.- Introducción 2.- Comunicación por memoria común 3.- El problema de la sección crítica 4.- Soluciones hardware 5.- Semáforos 6.- Problemas clásicos de programación concurrente 7.- Construcciones lingüísticas 8.- Sincronización en POSIX 9.- Comunicación por mensajes 8 4

2.Comunicación por memoria común El problema de los productores y consumidores con buffer acotado Productor: proceso que produce elementos (a una cierta velocidad) y los deposita en un buffer. Consumidor: proceso que toma elementos del buffer y los consume (a una velocidad probablemente diferente a la del productor) Buffer: Estructura de datos que sirve para intercambiar información entre los procesos productores y consumidores. Actúa a modo de depósito para absorber la diferencia de velocidad entre productores y consumidores Ejemplo: buffer de impresora. 9 2.Comunicación por memoria común El problema de los productores y consumidores con buffer acotado C1 salida buffer C2 Consumidores contador entrada Productores P1 P2 10 5

2.Comunicación por memoria común Productores y consumidores con buffer acotado Variables compartidas: var buffer: array[0..n-1] of of elemento; proceso consumidor: entrada:=0, salida:=0 : 0..n-1; task consumidor; contador:= 0 : 0..n; var item: elemento; proceso repeat productor: task while contador= 0 do dono-op; productor; var item := := buffer[salida] item: elemento; repeat salida := :=(salida +1) mod n; n; item contador:=contador-1; := := producir(); while consumir(item); contador= n do dono-op; buffer[entrada] until false := := item; entrada end consumidor; := :=(entrada +1) mod n; n; contador:=contador+1; until false end productor; 11 2.Comunicación por memoria común Condiciones de carrera Corrección en programes secuenciales: el programa cumple con sus especificaciones (responde a unos invariantes o reglas de corrección). Corrección secuencial no implica corrección concurrente: Un programa que tiene una implementación secuencialmente correcta (correcta con un sólo hilo de ejecución) puede presentar problemas cuando se intenta introducir concurrencia en forma de hilos de ejecución. Condición de carrera: la ejecución de un conjunto de operaciones concurrentes sobre una variable compartida, deja la variable en un estado inconsistente con las especificaciones de corrección. Además, el resultado de la variable depende de la velocidad relativa en que se ejecutan las operaciones. Peligro potencial: Las condiciones de carrera pueden presentarse en algún escenario, pero no tienen por qué observarse en todas las posibles trazas de la ejecución del programa. 12 6

2.Comunicación por memoria común Ejemplo de un escenario de condición de carrera Productor: contador:= contador+1; mov movreg1, contador; inc increg1; mov movcontador, reg1; reg1; Consumidor: contador:= contador-1; mov movreg2, contador; dec decreg2; mov movcontador, reg2; reg2; Inicialmente: contador =5 T Proceso Operación reg1 reg2 contador 0 Prod. mov contador, reg1 5? 5 1 Prod. inc reg1 6? 5 2 Cons. mov contador, reg2? 5 5 3 Cons. dec reg2? 4 5 4 Cons. mov reg2, contador? 4 4 5 Prod mov reg1, contador 6? 6 incorrecto 13 2.Comunicación por memoria común Criterio de corrección en programas concurrentes El criterio de corrección/consistencia más usual para programas concurrentes es: Seriabilidad (consistencia secuencial): El resultado de la ejecución concurrente de un conjunto de operaciones ha de ser equivalente al resultado de ejecutar secuencialmente cada una de las operaciones, en alguno de los ordenes secuenciales posibles. Condición de carrera = no seriabilidad: no hay ninguna posible ejecución secuencial de un conjunto de operaciones que de el mismo resultado que la ejecución concurrente. 14 7

2.Comunicación por memoria común Ejemplo de seriabilidad La ejecución concurrente de op1, op2 y op3 : op1 op2 op3 se considera correcta si el estado final de los datos compartidos es igual al estado en que quedarían después de alguna de las siguientes ejecuciones secuenciales: op1 ; op2 ; op3 o op1 ; op3 ; op2 o op2 ; op1 ; op3 o op2 ; op3 ; op1 o op3 ; op1 ; op2 o op3 ; op2 ; op1. Ejemplo numérico: sea una variable x con valor inicial 3 sobre la que se pueden realizar dos operaciones: op1: incremento de 8 op2: multiplicación por 5 Resultados correctos de op1 op2 : 55 y 23 15 Comunicación y sincronización de procesos Contenido 1.- Introducción 2.- Comunicación por memoria común 3.- El problema de la sección crítica 4.- Soluciones hardware 5.- Semáforos 6.- Problemas clásicos de programación concurrente 7.- Construcciones lingüísticas 8.- Sincronización en POSIX 9.- Comunicación por mensajes 16 8

3.El problema de la sección crítica Concepto de sección crítica Una sección crítica es una zona de código en la que se accede a variables compartidas por varios procesos. Problemas potenciales: puede introducir condiciones de carrera si no se adoptan las medidas adecuadas. Posible solución: sincronizar el acceso a los datos de manera que mientras un proceso ejecuta su sección crítica ningún otro proceso ejecuta la suya (exclusión mútua). 17 3. El problema de la sección crítica ormulación del problema de la sección crítica Sean n procesos compitiendo para acceder a datos compartidos Cada proceso tiene una zona de código, denominada sección crítica, en la que accede a los datos compartidos. Problema: encontrar un protocolo del tipo: protocolo de de entrada sección CRÍTICA protocolo de de salida sección RESTANTE Que satisfaga las tres condiciones siguientes : 18 9

3. El problema de la sección crítica Solución al problema de la sección crítica Cualquier solución al problema de la sección crítica ha de cumplir tres requisitos: Exclusión mútua: si un proceso está ejecutando su sección crítica ningún otro proceso puede estar ejecutando la suya. Progreso: si ningún proceso está ejecutando su sección crítica y hay otros que desean entrar a las suyas, entonces la decisión de qué proceso entrará a la sección crítica se toma en un tiempo finito y sólo puede ser seleccionado uno de los procesos que desean entrar. Espera limitada: Después de que un proceso haya solicitado entrar en su sección crítica, existe un límite en el número de veces que se permite que otros procesos entren a sus secciones críticas. 19 3. El problema de la sección crítica Solución al problema de la sección crítica Supuestos: Los procesos se ejecutan a velocidad no nula. La corrección no ha de depender de hacer suposiciones sobre la velocidad relativa de ejecución de los procesos. 20 10

3. El problema de la sección crítica Ejemplo: Algoritmo que soluciona el caso para dos procesos Variables compartidas: var varturno :: 0..1; 0..1; task Pi; while turno <> i do no-op; sección CRÍTICA turno := j; sección RESTANTE end Pi; task Pj; while turno <> j do no-op; sección CRÍTICA turno := i; sección RESTANTE end Pj; No satisface el requisito del progreso 21 Comunicación y sincronización de procesos Contenido 1.- Introducción 2.- Comunicación por memoria común 3.- El problema de la sección crítica 4.- Soluciones hardware 5.- Semáforos 6.- Problemas clásicos de programación concurrente 7.- Construcciones lingüísticas 8.- Sincronización en POSIX 9.- Comunicación por mensajes 22 11

4. Soluciones hardware Soluciones hardware al problema de la sección crítica Las soluciones hardware son soluciones a nivel de instrucciones del lenguaje máquina: Deshabilitación de interrupciones Instrucción test_and_set atómica (indivisible). Instrucción swap atómica. 23 4. Soluciones hardware Deshabilitación de interrupciones La deshabilitación de interrupciones se realiza utilizando las instrucciones: DI : Deshabilitar interrupciones EI : Habilitar interrupciones Se consigue la exclusión mútua inhibiendo los cambios de contexto durante la sección crítica, obligando así a que los procesos se ejecuten de manera atómica. Solución únicamente viable al nivel del núcleo del sistema operativo: puesto que no es deseable dejar el control de las interrupciones en manos de los procesos de usuario. Las instrucciones DI y EI sólo se pueden ejecutar en modo privilegiado. DI DI sección CRÍTICA EI EI sección RESTANTE 24 12

4. Soluciones hardware Operación test and set atómica La operación test_and_set permite evaluar y modificar una variable atómicamente en una sola operación de ensamblador. La especificación funcional de esta operación es: function testandset(var objetivo: boolean): boolean; begin testandset := := objetivo; objetivo := := TRUE; end end atómicamente! 25 4. Soluciones hardware Solución al problema de la s.c. con test_and_set Variables compartidas: var varllave := := ALSE :: boolean; Espera activa: el proceso no se suspende por esperar la entrada a la SC task Pi; Pi; while testandset(llave) do do no-op; no-op; sección CRÍTICA llave llave := := ALSE; ALSE; sección secciónrestante end end Pi; Pi; 26 13

4. Soluciones hardware Solución a la s.c. con test and set y espera limitada La solución anterior no satisface el requisito de la espera limitada. Variables compartidas: var varesperando := := ALSE :: array[0..n-1] of of boolean; cerradura := := ALSE :: boolean; 27 4. Soluciones hardware Solución a la s.c. con test and set y espera limitada task Pi; Pi; Algoritmo del proceso i: var varj: j: 0..n-1; llave: boolean;...... esperando[i]:= TRUE; llave llave := := TRUE; while esperando[i] and andllave llavedo dollave:=testandset(cerradura); esperando[i] := := ALSE; sección CRÍTICA j:=i+1 mod n; n; while (j<>i) and and (not (notesperando[j]) do doj:=j+1 mod n; n; if ifj=i then cerradura := := ALSE else elseesperando[j] := := ALSE; sección RESTANTE end endpi; Pi; 28 14

4. Soluciones hardware Solución a la s.c. con test and set y espera limitada Proceso 0 (i=0) esperando[i]:= TRUE; llave := TRUE; while esperando[i] and llave do llave:=testandset(cerradura); esperando[i] := ALSE; cerradura esperando j:=i+1 mod n; while (j<>i) and (not esperando[j]) do j:=j+1 mod n; if j=i then cerradura := ALSE else esperando[j] := ALSE;... Proceso 4 (i=4) 0 1 2 3 4 5 6 7... 29 4. Soluciones hardware Solución a la s.c. con test and set y espera limitada Proceso 0 (i=0) esperando[i]:= TRUE; llave := TRUE; while esperando[i] and llave do llave:=testandset(cerradura); esperando[i] := ALSE; cerradura esperando j:=i+1 mod n; while (j<>i) and (not esperando[j]) do j:=j+1 mod n; if j=i then cerradura := ALSE else esperando[j] := ALSE;... Proceso 4 (i=4) V 0 1 2 3 4 5 6 7... 30 15

4. Soluciones hardware Solución a la s.c. con test and set y espera limitada Proceso 0 (i=0) esperando[i]:= TRUE; llave := TRUE; while esperando[i] and llave do llave:=testandset(cerradura); esperando[i] := ALSE; cerradura V esperando j:=i+1 mod n; while (j<>i) and (not esperando[j]) do j:=j+1 mod n; if j=i then cerradura := ALSE else esperando[j] := ALSE;... Proceso 4 (i=4) V 0 1 2 3 4 5 6 7... 31 4. Soluciones hardware Solución a la s.c. con test and set y espera limitada Proceso 0 (i=0) esperando[i]:= TRUE; llave := TRUE; while esperando[i] and llave do llave:=testandset(cerradura); esperando[i] := ALSE; cerradura V esperando j:=i+1 mod n; while (j<>i) and (not esperando[j]) do j:=j+1 mod n; if j=i then cerradura := ALSE else esperando[j] := ALSE;... Proceso 4 (i=4) 0 1 2 3 4 5 6 7... 32 16

4. Soluciones hardware Solución a la s.c. con test and set y espera limitada Proceso 0 (i=0) esperando[i]:= TRUE; llave := TRUE; while esperando[i] and llave do llave:=testandset(cerradura); esperando[i] := ALSE; cerradura V esperando j:=i+1 mod n; while (j<>i) and (not esperando[j]) do j:=j+1 mod n; if j=i then cerradura := ALSE else esperando[j] := ALSE;... Proceso 4 (i=4) V 0 1 2 3 4 5 6 7... 33 4. Soluciones hardware Solución a la s.c. con test and set y espera limitada Proceso 0 (i=0) esperando[i]:= TRUE; llave := TRUE; while esperando[i] and llave do llave:=testandset(cerradura); esperando[i] := ALSE; cerradura V esperando j:=i+1 mod n; while (j<>i) and (not esperando[j]) do j:=j+1 mod n; if j=i then cerradura := ALSE else esperando[j] := ALSE;... Proceso 4 (i=4) V 0 1 2 3 4 5 6 7... 34 17

4. Soluciones hardware Solución a la s.c. con test and set y espera limitada Proceso 0 (i=0) esperando[i]:= TRUE; llave := TRUE; while esperando[i] and llave do llave:=testandset(cerradura); esperando[i] := ALSE; cerradura V esperando j:=i+1 mod n; while (j<>i) and (not esperando[j]) do j:=j+1 mod n; if j=i then cerradura := ALSE else esperando[j] := ALSE;... Proceso 4 (i=4) V 0 1 2 3 4 5 6 7... 35 4. Soluciones hardware Solución a la s.c. con test and set y espera limitada Proceso 0 (i=0) esperando[i]:= TRUE; llave := TRUE; while esperando[i] and llave do llave:=testandset(cerradura); esperando[i] := ALSE; cerradura V esperando j:=i+1 mod n; while (j<>i) and (not esperando[j]) do j:=j+1 mod n; if j=i then cerradura := ALSE else esperando[j] := ALSE;... Proceso 4 (i=4) 0 1 2 3 4 5 6 7... 36 18

4. Soluciones hardware Solución a la s.c. con test and set y espera limitada Proceso 0 (i=0) esperando[i]:= TRUE; llave := TRUE; while esperando[i] and llave do llave:=testandset(cerradura); esperando[i] := ALSE; cerradura esperando j:=i+1 mod n; while (j<>i) and (not esperando[j]) do j:=j+1 mod n; if j=i then cerradura := ALSE else esperando[j] := ALSE;... Proceso 4 (i=4) 0 1 2 3 4 5 6 7... 37 4. Soluciones hardware Solución a la s.c. con test and set y espera limitada Proceso 0 (i=0) esperando[i]:= TRUE; llave := TRUE; while esperando[i] and llave do llave:=testandset(cerradura); esperando[i] := ALSE; cerradura esperando j:=i+1 mod n; while (j<>i) and (not esperando[j]) do j:=j+1 mod n; if j=i then cerradura := ALSE else esperando[j] := ALSE;... Proceso 4 (i=4) 0 1 2 3 4 5 6 7... 38 19

4. Soluciones hardware Operación swap atómica La operación swap permite intercambiar atómicamente dos variables en una sola operación de ensamblador. La especificación funcional de esta operación es: function swap(var a,b: a,b: boolean); var vartemp :: boolean; begin temp:= a; a; a:=b; b := := temp; end end atómicamente! 39 4. Soluciones hardware Solución a la s.c con swap Variables compartidas: var varcerradura := := ALSE ALSE :: boolean; Espera activa task Pi; Pi; var varllave: boolean; llave llave := := TRUE while swap(cerradura, llave) until llave llave = ALSE; sección CRÍTICA cerradura := := ALSE; sección RESTANTE end endpi; Pi; 40 20

Comunicación y sincronización de procesos Contenido 1.- Introducción 2.- Comunicación por memoria común 3.- El problema de la sección crítica 4.- Soluciones hardware 5.- Semáforos 6.- Problemas clásicos de programación concurrente 7.- Construcciones lingüísticas 8.- Sincronización en POSIX 9.- Comunicación por mensajes 41 5. Semáforos Definición de semáforo Tipo de datos que toma valores enteros y sobre el que se definen las siguientes operaciones atómicas: S: semaforo(n); (* semáforo S con valor inicial N >=0 *) P(S) S:=S-1; atómicamente! if S<0 then esperar(s); V(S) S:=S+1; if S<=0 then despertar(s); atómicamente! La operación esperar(s) suspende al proceso que ha invocado P() y lo introduce en una cola de espera asociada a S. La operación despertar(s) extrae un proceso de la cola de espera asociada a S y lo activa. Semáforo P V contador cola 42 21

5. Semáforos Solución al problema de la sección crítica con semáforos Los semáforos son un mecanismo de sincronización que no requiere espera activa Variables compartidas: var varmutex: semaforo(1); (* (* valor inicial 1 *) *) task taskpi; Pi;...... P(mutex); sección CRÍTICA V(mutex); sección RESTANTE...... end endpi; Pi; 43 5. Semáforos Implementación de semáforos ESTRUCTURAS DE CONTROL DEL SISTEMA : Vector de semáforos Tabla de procesos Semáforo-i Contador Cola de procesos esperando en el semáforo i P. primero P. último PCB 8 Estado: SUSP Evento: Sem-i... P. siguiente PCB 4 PCB 2 44 22

lujo de Control del S.O. semaforo(valor) Llamadas al Sistema relacionadas con semáforos P(S) V(S) Activación del Sistema Operativo Guardar parte del contexto de usuario, para realizar cambio de modo de ejecución (usuario->núcleo) Reservar un semáforo S; S.contador:= valor; S.contador:= S.contador-1; Si S. contador < 0 entonces Pasar a suspendido al proceso Si S.contador en ejecución; Insertarlo en S.cola; S.contador:= S.contador+1; Si S.contador <= 0 entonces p:=extraer proceso de S.cola; Pasar p a preparado Si no Planificador: selección del próximo proceso Si no Realizar cambio de modo de ejecución (núcleo -> usuario). Recuperar contexto de usuario. 45 5. Semáforos Semáforos versus espera activa Espera activa: El proceso que espera entrar en la sección crítica desaprovecha el tiempo de CPU comprobando cuando puede entrar (ejecutando las instrucciones del protocolo de entrada). Semáforos: La espera se realiza en la cola del semáforo, que es una cola de procesos suspendidos. El proceso que espera entrar en la sección crítica no utiliza CPU; está suspendido. Proceso: EntrdaSC; SecciónCrítica; SalidaSC; P1,P2,P2:Proceso; Espera activa Espera activa P1 P2 P3 P1 P2 P3 q P2 P3 P3 Duración se la sección crítica 2q Espera pasiva P1 P1 P2 P2 P3 P3 46 23

5. Semáforos Semáforos: ejemplos de utilización Un semáforo es un mecanismo de sincronización de uso general: Para conseguir exclusión mútua. Para forzar relaciones de precedencia, como por ejemplo: El proceso Pj debe ejecutar B después de que el proceso Pi haya ejecutado A. var sinc: semaforo(0); task Pi;... A; V(sinc);... task Pj;... P(sinc) B;... 47 5. Semáforos Semáforos: problemas derivados de una utilización incorrecta Interbloqueos: Hay un conjunto de procesos en el que todos esperan (indefinidamente) un evento que sólo otro proceso del conjunto puede producir. Ejemplo: var s1: semaforo(1); s2: semaforo(1); task P1; task P2;...... P(s1); P(s2); P(s2); P(s1); V(s1); V(s1); V(s2); V(s2); Escenario: P1 P1 P(s1); P2 P2 P(s2); P2 P2 P(s1); P1 P1 P(s2); Sistema en en situación de de interbloqueo 48 24

Comunicación y sincronización de procesos Contenido 1.- Introducción 2.- Comunicación por memoria común 3.- El problema de la sección crítica 4.- Soluciones hardware 5.- Semáforos 6.- Problemas clásicos de programación concurrente 7.- Construcciones lingüísticas 8.- Sincronización en POSIX 9.- Comunicación por mensajes 49 6. Problemas clásicos de concurrencia Problemas clásicos de programación concurrente Existe una serie de problemas clásicos que se utilizan como banco de pruebas de los diferentes mecanismos de sincronización entre procesos: Los productores y los consumidores Los lectores y los escritores Los cinco filósofos El barbero dormilón... 50 25

6. Problemas clásicos de concurrencia El problema de los productores y consumidores con buffer acotado C1 salida buffer C2 Consumidores contador entrada Productores P1 P2 51 6. Problemas clásicos de concurrencia Los productores y consumidores Variables compartidas var varbuffer: array[0..n-1]of elemento; entrada:=0, salida:=0, contador:= 0 :: 0..n-1; lleno: semaforo(0); vacio: semaforo(n), mutex: semaforo(1); 52 26

6. Problemas clásicos de concurrencia Los productores y consumidores task taskproductor; var varitem: elemento; repeat repeat item item := := producir(); P(vacio); P(mutex); buffer[entrada] := := item; item; entrada := :=(entrada +1) +1) mod modn; n; contador:=contador+1; V(mutex); V(lleno); until until false false end endproductor; task taskconsumidor; var varitem: elemento; repeat repeat P(lleno); P(mutex); item item := := buffer[salida] salida salida := :=(salida +1) +1) mod modn; n; contador:=contador-1; V(mutex); V(vacio); consumir(item); until until false false end endproductor; 53 6. Problemas clásicos de concurrencia Los lectores y los escritores Problemade loslectoresy losescritores Hay un conjunto de datos comunes (un fichero, una base de datos, etc.) Los procesos lectores, acceden a los datos en modo de sólo lectura Los procesos escritores, acceden a los datos en modo lectura-escritura Especificación del protocolo: reglas de corrección Diversos lectores pueden leer concurrentemente. Los escritores se excluyen mútuamente entre ellos Los escritores se excluyen mútuamente con los lectores. 54 27

6. Problemas clásicos de concurrencia Los lectores y los escritores Especificación del protocolo: reglas de corrección L L STOP E E E STOP E E STOP L L 55 6. Problemas clásicos de concurrencia Loslectores y escritores Especificación del protocolo: reglas de prioridad Primera variante de los Lectores-Escritores: (Prioridad a los lectores) Si hay lectores leyendo y escritores esperando, entonces un nuevo lector tiene preferencia sobre el escritor que espera. Hay inanición para los escritores, si no paran de llegar lectores Segunda variante de los Lectores-Escritores: (Prioridad a los escritores) Si hay escritores esperando, éstos siempre tienen preferencia sobre nuevos lectores que lleguen Hay inanición para los lectores, si no paran de llegar escritores Tercera variante, sin inanición para ningún tipo de proceso 56 28

6. Problemas clásicos de concurrencia Los lectores y los escritores Especificación del protocolo: reglas de prioridad L L STOP E L E 1ª variante 2ª variante L STOP E E L 57 6. Problemas clásicos de concurrencia Los lectores y los escritores (semáforos) Solución a la primera variante: Inanición para los escritores Variables compartidas: var varmutex: semaforo(1); esc escsemaforo(1); nlectores:=0 :: integer; task taskescritor; P(esc); P(esc); escribir(); V(esc); V(esc); end endescritor; task tasklector; P(mutex); nlectores := := nlectores + 1; 1; if ifnlectores = 1 then then P(esc); P(esc); V(mutex); leer(); leer(); P(mutex); nlectores := := nlectores --1; 1; if ifnlectores = 0 then thenv(esc); V(mutex); end endlector; 58 29

Comunicación y sincronización de procesos Contenido 1.- Introducción 2.- Comunicación por memoria común 3.- El problema de la sección crítica 4.- Soluciones hardware 5.- Semáforos 6.- Problemas clásicos de programación concurrente 7.- Construcciones lingüísticas 8.- Sincronización en POSIX 9.- Comunicación por mensajes 59 7. Construcciones lingüísticas Con el fin de simplificar la programación de aplicaciones concurrentes, algunos lenguajes de programación proporcionan herramientas (construcciones lingüísticas) que facilitan la sincronización entre las tareas y proporcionan un modelo de programación uniforme. Monitores Tipos protegidos en ADA Métodos synchronized en Java Soluciones a nivel de lenguaje de programación Soluciones a nivel de sistema operativo Soluciones hardware 60 30

7.1 Monitores Concepto Un monitor es un tipo de datos que encapsula datos y operaciones. Proporciona: Exclusión mútua. Sincronización. 61 7.1 Monitores Sintaxis: type nombre_monitor = monitor... declaración de variables. procedure entry P1(...); begin... end; function entry 2(...); begin... end;... begin... Código de inicialización end; Variables internas al al monitor: Variables compartidas Variables condición Métodos de de acceso: Unica vía vía de de acceso a las las variables compartidas Exclusión mutua Se Se invoca automáticamente al al instanciar el el monitor y antes antes de de ser ser accedido por por ningún proceso Se Se utiliza para para la la inicialización de de las las variables del del monitor 62 31

7.1 Monitores Variables de tipo condición: Para definir esquemas complejos de sincronización, se pueden definir las variables del tipo condition. var x: condition; Sobre las variables condition se pueden realizar las siguientes operaciones: x.wait; Causa la suspensión (en una cola asociada a x) del proceso que invocó la operación. x.signal; Se reanuda (si existe) un proceso suspendido en la cola asociada a x. x.awaited; Indica el número de procesos suspendidos en la cola asociada a x. 63 7.1 Monitores Productores-consumidores con monitores Monitor PROGRAMA PRINCIPAL B:buffer_limitado; task taskproductor; var: var: elemento:item; repeat...producir un un elemento B.insertar(elemento); until untilfalse; end endproductor; task taskconsumidor; var: var: elemento:item; repeat B.extraer(elemento);...Procesar elemento until untilfalse; end endconsumidor; 64 32

Productores-consumidores con monitores type typebuffer_limitado = monitor const constn=100; n=100; cont, cont, entrada, salida:integer; lleno, lleno, vacio: vacio: condition; buffer: buffer: array[0..n-1] of of item; item; procedure entry entry insertar (elem:item); begin begin......... end; end; procedure entry entry extraer extraer (var (var elem:item); begin begin......... end; end; begin begin entrada:=0; salida:=0;cont:=0; end; end; MONITOR procedure entry insertar (elem:item); begin if cont=n then lleno.wait; cont:=cont+1; buffer[entrada]:=item; entrada:=(entrada + 1) mod n; vacio.signal; end; procedure entry extraer(var elem:item); begin if cont=0 then vacio.wait; cont:=cont-1; item:=buffer[salida]; salida :=(salida + 1) mod n; lleno.signal; end; 65 7.1Monitores Variantes Existen diferentes variantes en la definición de un monitor según resuelvan el siguiente problema: Un proceso P ejecuta x.signal y activa a otro proceso Q, Potencialmente P y Q pueden continuar su ejecución dentro del monitor. Cómo se garantiza la ejecución en exclusión mutua en el monitor? Modelo de Hoare: El proceso que invoca la operación x.signal (P) se suspende (en una cola de urgencia ) de forma que el proceso reanudado por la operación x.signal (Q) pasa a ejecutarse dentro del monitor. Modelo de Lampson y Redell: El proceso P continúa ejecutándose y Q se ejecutará cuando el monitor quede libre. Modelo de Brinch-Hansen: La operación x.signal ha de ser la última operación que un proceso invoca antes de salir del monitor. 66 33

7.1 Monitores Modelo de colas Cola de entrada MONITOR Variable condición c1 Zona de espera del monitor (procesos suspendidos) Variable condición c2 c1.wait c1.signal c2.wait c2.signal Datos Procedimientos y funciones Cola urgente (Hoare) Salida 67 7.1 Monitores Implementación de monitores con semáforos Variables globales, por cada monitor se definen: var varmutex: semaforo(1); urgente: semaforo(0); (*cola de de urgencia*) cont_urg: integer:=0; Para cada procedimiento o funcion, se genera: P(mutex);...... Cuerpo de de ; ; if ifcont_urg > 0 then thenv(urgente) else elsev(mutex); 68 34

7.1 Monitores Implementación de monitores con semáforos Para cada variable condición X, se define: var var x_sem: semaforo(0); x_cont: integer:=0; Operación X.wait x_cont:= x_cont+1; if ifcont_urg > 0 then thenv(urgente) else elsev(mutex); P(x_sem); x_cont:= x_cont-1; Operación X.signal if ifx_cont > 0 then thenbegin cont_urg:= cont_urg + 1; 1; V(x_sem); P(urgente); cont_urg:= cont_urg --1; 1; end; end; 69 7.1 Monitores Lectores-escritores con monitores Monitor PROGRAMA PRINCIPAL var var le:le-control; task tasklector(); begin repeat le.pre-leer(); leer(); le.post-leer(); until untilfalse; end endlector; task taskescritor(); begin repeat le.pre-escribir(); escribir(); le.post-escribir(); until untilfalse; end endescritor; 70 35

7.1 Monitores Lectores-escritores con monitores MONITOR type typele-control = monitor; var varlectores, escritores :Integer; leer, leer, escribir :: condition; procedure entry entrypre-leer(); if if escritores > 0 then thenleer.wait; lectores := := lectores+1; leer.signal; (* (* despertar al al siguiente *) *) end; end; procedure entry entrypost-leer(); lectores := := lectores-1; if iflectores = 0 then thenescribir.signal; end; end; Inanición para para escritores procedure entry entrypre-escribir(); if if escritores > 0 or orlectores > 0 then thenescribir.wait; escritores := := escritores+1; end; end; procedure entry entrypost-escribir(); escritores := := escritores-1; if ifleer.awaited > 0 then thenleer.signal; else elseescribir.signal; end; end; begin begin lectores:=0; escritores:=0; end. end. 71 7.1 Monitores Lectores-escritores con monitores MONITOR type typele-control = monitor; var varlectores, escritores :Integer; leer, leer, escribir :: condition; procedure entry entrypre-leer(); if if escritores > 0 or orescribir.awaited > 0 then thenleer.wait; lectores := := lectores+1; leer.signal; (* (* despertar al al siguiente *) *) end; end; procedure entry entrypost-leer(); lectores := := lectores-1; if iflectores = 0 then thenescribir.signal; end; end; Inanición para para lectores procedure entry entrypre-escribir(); if if escritores > 0 or orlectores > 0 then thenescribir.wait; escritores := := escritores+1; end; end; procedure entry entrypost-escribir(); escritores := := escritores-1; if ifescribir.awaited > 0 then thenescribir.signal; else elseleer.signal; end; end; begin begin lectores:=0; escritores:=0; end. end. 72 36

7.1 Monitores Lectores-escritores con monitores MONITOR type typele-control = monitor; var varlectores, escritores :Integer; leer, leer, escribir :: condition; procedure entry entrypre-leer(); if if escritores > 0 or orescribir.awaited > 0 then thenleer.wait; lectores := := lectores+1; leer.signal; (* (* despertar al al siguiente *) *) end; end; procedure entry entrypost-leer(); lectores := := lectores-1; if iflectores = 0 then thenescribir.signal; end; end; Sin Sin Inanición procedure entry entrypre-escribir(); if if escritores > 0 or orlectores > 0 then thenescribir.wait; escritores := := escritores+1; end; end; procedure entry entrypost-escribir(); escritores := := escritores-1; if ifleer.awaited > 0 then thenleer.signal; else elseescribir.signal; end; end; begin begin lectores:=0; escritores:=0; end. end. 73 7.1 Monitores Monitores: espera condicional Cuando se produce una llamada a x.signal, qué proceso se activa? El monitor permite una variante de la operación wait sobre una variable condición para que, cuando se produzca la operación signal, se active a los procesos suspendidos por orden de prioridad. Se define la siguiente construcción: x.wait(c) donde: c es una expresión entera que se evalúa cuando se realiza la operación wait. El valor de c se almacena junto al proceso suspendido. Al invocar la operación signal, se activa el proceso que tenga mayor prioridad (menor valor numérico de c). 74 37

7.1 Monitores Monitores espera condicional Asignación de recursos basada en tiempo de uso. De aquellos procesos que se encuentren esperando por el recurso ocupado, se reanudará aquel que lo vaya a usar durante menos tiempo. type typeasignacion-recurso = monitor var var ocupado: boolean; x: x: condition; procedure entry adquirir(tiempo: integer); begin if ifocupado then x.wait(tiempo); ocupado:= true; true; end; end; procedure entry liberar; begin ocupado:= false; x.signal; end; end; begin ocupado:= false; end. end. 75 7.2 Objetos protegidos Objetos protegidos de ADA : declaración Un objeto protegido encapsula datos que son accedidos simultáneamente por varias tareas. Las tareas acceden a los datos del objeto utilizando operaciones protegidas, las cuales pueden ser funciones, procedimientos y entradas. protected [type] Nombre[(Discriminantes)] is is procedure procedure Pnombre(Params); function Pnombre(Params); nombre(params) function return Un_Tipo; entry nombre(params) Enombre(Params); return Un_Tipo; entry entry Enombre(Params); private Datos_Protegidos : Su_Tipo; end end Nombre; 76 38

7.2 Objetos protegidos Objetos protegidos de ADA La especificación tiene dos partes: Una pública, donde se declaran las operaciones protegidas. Una privada donde se declaran los datos protegidos. La parte privada no es visible por los clientes del objeto protegido. especificación protected [type] Nombre[(Discriminantes)] is is procedure Pnombre(Params); function nombre(params) return Un_Tipo; entry entry Enombre(Params); private Datos_Protegidos : Su_Tipo; end end Nombre; 77 7.2 Objetos protegidos Objetos protegidos de ADA: declaración En el cuerpo del objeto se implementan las operaciones protegidas. protected body body Nombre is is --- --- cuerpo end end Nombre; ADA permite declarar tipos protegidos o instancias individuales. especificación protected [type] Nombre[(Discriminantes)] is is procedure Pnombre(Params); function nombre(params) return Un_Tipo; entry entry Enombre(Params); private Datos_Protegidos : Su_Tipo; end end Nombre; Objeto_1: Nombre; Objeto_2: Nombre; instanciación 78 39

7.2 Objetos protegidos Objetos protegidos de ADA: control de concurrencia Las funciones permiten consultar el objeto protegido y, por tanto, pueden ejecutarse simultáneamente varias funciones. Cuando una tarea está ejecutando un procedimiento o una entrada del objeto protegido, otra tarea interesada en acceder al objeto protegido queda detenida hasta que éste queda libre. Las entradas tienen asociadas una condición lógica denominada barrera (o guarda). Si en el momento de llamar al objeto la barrera es cierta, la tarea ejecuta la entrada. En caso contrario, la tarea queda detenida en dicha entrada. entry entry Una_Entrada (Params) when when Alguna_Condición is is var_locales; begin begin...... end end Una_Entrada; La La expresión de de una una barrera no no puede contener parámetros de de la la entrada.! 79 7.2 Objetos protegidos Objetos protegidos de ADA: control de concurrencia Las barreras se revaluan cuando finaliza la ejecución de una entrada o un procedimiento. Si alguna barrera es ahora cierta se elige una tarea detenida por dicha barrera y reanuda su ejecución. Las tareas detenidas en barreras tienen prioridad cuando son despertadas frente a aquellas que están esperando fuera del objeto protegido. ❺❻❼ ❸❹ ❷ E1 E2 ❶ 80 40

7.2 Objetos protegidos Construcción de semáforos con objetos protegidos de ADA especificación protected type typesemaforo (Inicial:integer:=1) is is entry P; P; procedure V; V; private contador:integer:=inicial; end endsemaforo; utilización Un_semaforo: Semaforo(5);...... Un_semaforo.P;...... Un_semaforo.V; cuerpo protected body Semaforo is is entry P when contador>0 is is begin contador:=contador-1; end endp; P; procedure V is is begin contador:=contador+1; end endv; V; end endsemaforo; 81 7.2 Objetos protegidos Ejemplo en ADA: el buffer acotado procedure Prodcons is n : constant Integer := 10; subtype Indice is Integer range 0..n-1; subtype Cantidad is Integer range 0..n; subtype Item is Integer ; type Buffers is array (Indice) of Item; task task type typeproductor; task task type typeconsumidor; Un_Buffer: Buffer; Prod_1: Productor; Prod_2: Productor; Cons :: Consumidor; protected type typebuffer is is entry Poner (x (x:: in initem); entry Quitar (x (x:: out outitem); private Buf: Buf: Buffers; Entrada :: Indice := := 0; 0; Salida :: Indice := := 0; 0; Contador: Cantidad := := 0; 0; end endbuffer ;; 82 41

7.2 Objetos protegidos Ejemplo en ADA: el buffer acotado protected body Buffer is entry Poner (x : in Item) when Contador < n begin Buf(entrada) := x; Entrada := (Entrada + 1) mod n; Contador := Contador + 1; end Poner; entry Quitar (x : out Item) when Contador > 0 begin x:= Buf(Salida); Salida := (Salida + 1) mod n; Contador := Contador - 1; end Quitar; is is end Buffer ; 83 7.2 Objetos protegidos Ejemplo en ADA: el buffer acotado task task body Productor is is x :: ITEM; begin loop loop x := :=...;...; Un_Buffer.Poner(x); -- --otras acciones end end loop; end endproductor ;; task task body Consumidor is is x :: ITEM; begin loop loop Un_Buffer.Quitar(x); -- --otras acciones end end loop; end endconsumidor; begin null; end ProdCons; 84 42

Comunicación y sincronización de procesos Contenido 1.- Introducción 2.- Comunicación por memoria común 3.- El problema de la sección crítica 4.- Soluciones hardware 5.- Semáforos 6.- Problemas clásicos de programación concurrente 7.- Construcciones lingüísticas 8.- Sincronización en POSIX 9.- Comunicación por mensajes 85 8. Sincronización en POSIX POSIX ofrece dos primitivas de sincronización de hilos: los mutex (o cerrojos) y las variables condición. Mutex (cerrojos) Tienen dos estados posibles: Abierto ningún hilo es el propietario Cerrado el hilo que lo cierra es el propietario. Un mutex no puede tener dos hilos propietarios simultáneamente. Cuando un hilo intenta cerrar un mutex que ya ha sido cerrado, se suspende hasta que el hilo propietario lo abra. Sólo el hilo propietario puede abrir el mutex. Creación e inicialización de los mutex: p_thread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; 86 43

8. Sincronización en POSIX Llamada Descripción pthread_mutex_lock (mut) Si el mutex mut estaba abierto, lo cierra y el hilo que lo cierra es el propietario del mutex. Si estaba cerrado, suspende(*) al hilo hasta que se abra el mutex. pthread_mutex_unlock (mut) Abre el mutex mut. Solo el hilo propietario del mutex puede abrirlo ( ** ). pthread_mutex_trylock(mut) Igual que pthread_mutex_lock pero en lugar de suspender al hilo si el semáforo estaba cerrado, retorna immediatamente con un código de error. (*) Hay tipos de mutex, que le permiten al propietario cerrarlo varias veces sin bloquearse. Con este tipo de mutex, el propietario debe abrirlo tantas veces como lo hubiera cerrado para dejarlo finalmente abierto. (**) Hay sistemas, como Redhat 5.1, que permiten que otros hilos abran el mutex, sin embargo este funcionamiento no es portable. 87 8. Sincronización en POSIX Variables condición en POSIX Las variables condición son un tipo abstracto de datos con tres operaciones básicas: wait: suspende al proceso que la invoca en la condición. signal: activa un proceso suspendido en la condición broadcast: activa a todos los procesos suspendidos en la condición Las variables condición siempre deben estar asociadas a un mutex. Además existen métodos para limitar el tiempo que un hilo está bloqueado en una variable condición. Creación e inicialización de atributos: p_thread_cond_t c1 = PTHREAD_COND_INITIALIZER; 88 44

8. Sincronización en POSIX Variables condición en POSIX Llamada pthread_cond_wait(cond, mut) pthread_cond_signal(cond) pthread_cond_broadcast(cond) pthread_cond_timedwait (cond, mut,duracion) Descripción De forma atómica, realiza la operación p_thread_mutex_unlock sobre mut, y bloquea al hilo en la variable condición cond. Cuando es despertado, el hilo cierra nuevamente el mutex mut (realizando la operación p_thread_mutex_lock. Despierta a uno de los hilos que están bloqueados en la variable condición. Si no hay hilos bloqueados, no sucede nada. Despierta todos los hilos bloqueados sobre cond. Igual que pthread_cond_wait pero si antes de duracion no se ha despertado al hilo, la llamada finalizará con un código de error. Al despertar, el hilo que invoca la llamada, vuelve a cerrar el mutex mut. 89 8. Sincronización en POSIX El productor consumidor en POSIX (i) Variables globales: #define n 10 10 int intentrada, salida, contador; int int buffer[n]; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t lleno lleno = PTHREAD_COND_INITIALIZER; pthread_cond_t vacio = PTHREAD_COND_INITIALIZER; 90 45

8. Sincronización en POSIX El productor consumidor en POSIX (i) void void *productor(void * arg){ arg){ int inti; i; for for (i=0; (i=0; i<100; i<100; i++) i++) Insertar(i); pthread_exit(0); } void void *consumidor(void * arg){ arg){ int inti; i; for for (i=0; (i=0; i<100; i<100; i++) i++) printf( %d,, Extraer()); pthread_exit(0); } main( main( )){ pthread_t th_a, th_a, th_b; th_b; entrada = salida salida = contador = 0; 0; } pthread_create(&th_a, NULL,productor,NULL); pthread_create(&th_b, NULL,consumidor,NULL); pthread_join(th_a, NULL); NULL); pthread_join(th_b, NULL); NULL); exit(0); exit(0); 91 8. Sincronización en POSIX El productor consumidor en POSIX (i) Insertar (int (intdato) { pthread_mutex_lock(&mutex); while (contador >=n) pthread_cond_wait(&lleno, &mutex); buffer[entrada]= dato; dato; entrada= (entrada+1) % n; n; contador= contador+1; pthread_cond_broadcast(&vacio); pthread_mutex_unlock(&mutex); } int intextraer (()){ int intdato; pthread_mutex_lock(&mutex); while (contador == 0) pthread_cond_wait(&vacio, &mutex); dato dato = buffer[salida]; salida= salida= (salida+1) % n; n; contador=contador --1; 1; pthread_cond_broadcast(&lleno); pthread_mutex_unlock(&mutex); return returndato; } 92 46

Comunicación y sincronización de procesos Contenido 1.- Introducción 2.- Comunicación por memoria común 3.- El problema de la sección crítica 4.- Soluciones hardware 5.- Semáforos 6.- Problemas clásicos de programación concurrente 7.- Construcciones lingüísticas 8.- Sincronización en POSIX 9.- Comunicación por mensajes 93 9. Comunicación por mensajes Sistemas de mensajes Los sistemas de mensajes permiten la comunicación entre procesos con espacios de direcciones distintos, bien sean locales o remotos. Operaciones básicas (proporcionadas por el Sistema Operativo): send(dst,mensaje): enviar un mensaje a un destino. receive(org,mensaje): recibir un mensaje de un origen. P1 P2 mensaje 94 47

9. Comunicación por mensajes Variantes Según el modo de nombrar origen y destino: Comunicación directa: proceso a proceso. Comunicación indirecta: basada en puertos o buzones. Según la capacidad del enlace: Comunicación síncrona: el enlace tiene capacidad = 0. Comunicación asíncrona: el enlace tiene capacidad > 0. 95 9. Comunicación por mensajes Comunicación directa Los mensajes se direccionan a procesos. Los procesos necesitan conocer sus identificadores: las direcciones dst y org son identificadores de procesos. org puede ser un comodín, ANY. En este caso se recibe de cualquier proceso y ANY toma el valor del proceso emisor. Recibir de 20 P1 P15 A: proceso 15 De: proceso 20 96 48

9. Comunicación por mensajes Comunicación indirecta: puertos o buzones Los mensajes se envían a puertos: las direcciones dst y org son identificadores de puertos. Un puerto tiene un identificador único en el sistema. El protocolo TCP/IP utiliza puertos bien conocidos que sirven para invocar servicios de red. ftp: port 20 y 21 www: port 80 ntp: port 123 97 9. Comunicación por mensajes Comunicación indirecta: puertos Nodo xaloc Nodo garbi A: Servicio ftp Puerto 20 P2 Puerto 21 P1 Puerto 55 Puerto 90 Puerto 80 P3 98 49

9. Comunicación por mensajes Comunicación indirecta: puertos y buzones Puertos: permiten que varios procesos envíen, pero sólo puede haber un proceso asociado para recibir. Buzones: permiten que varios procesos se asocien para recibir. El sistema operativo selecciona qué proceso recibe el mensaje. 99 9. Comunicación por mensajes Operaciones sobre puertos Qué proceso puede recibir del puerto? Alternativas: a) El propietario: El proceso que lo crea es el propietario del puerto y es el único que puede recibir o destruir el puerto. Cuando el proceso propietario finaliza, se destruyen todos los puertos que posee. Son necesarias las siguientes operaciones: create(port): crea un puerto. destroy(port): destruye un puerto. b) El que se vincula al puerto: El puerto pertenece al S.O. y su existencia es independiente de los procesos que lo utilizan. Cuando un proceso se vincula a un puerto, es el único que puede recibir de él. bind(puerto): vincula un proceso con un puerto. 100 50

9. Comunicación por mensajes Comunicación síncrona La capacidad del enlace es cero: El enlace no almacena mensajes; no pueden existir mensajes enviados y pendientes de entrega. Cita o rendez-vous: La comunicación sólo tiene lugar cuando emisor y receptor han invocado sus operaciones respectivas send y receive. Implementación de la cita o rendez-vous: El primer proceso que llega a la cita se suspende esperando a que el otro llegue. 101 9. Comunicación por mensajes Mensajes: Comunicación síncrona P1 P2 P1 Escenario 1: send antes que receive P2 send suspendido recv send suspendido recv Escenario 2: receive antes que send 102 51

9. Comunicación por mensajes Comunicación asíncrona La capacidad del enlace es N: pueden haber mensajes enviados y pendientes de entrega Variantes: Capacidad limitada: N está acotado. Capacidad ilimitada: N no está acotado. Sincronización: Receive de enlace vacío: Opción bloqueante: suspender al proceso que la invoca. Opción no bloqueante : devolver un error al proceso que la invoca. Send a un enlace lleno: Opción bloqueante: suspender al proceso que la invoca. Opción no bloqueante : devolver un error al proceso que la invoca o perder el mensaje. 103 9. Comunicación por mensajes El problema de los Productores y Consumidores con mensajes: Los espacios de direcciones son separados. No hay variables comunes. Versión con: Comunicación directa. Comunicación síncrona o asíncrona (send y receive bloqueantes) task productor; var item : elemento; repeat item := producir(); send( consumidor, item ); until false; end productor; task consumidor; var item : elemento; repeat receive( productor, item ); consumir(item); until false; end consumidor; 104 52

9. Comunicación por mensajes El problema de los Productores y Consumidores con mensajes: Versión con: Comunicación directa. Comunicación asíncrona, con enlace de capacidad N (receive bloqueante, send no bloqueante) task taskproductor; var varitem :: elemento; m :: mensaje; repeat repeat item item := := producir(); receive( consumidor, m ); ); construir_msj(m, item); item); send( send( consumidor, m ); ); until untilfalse; end endproductor; task taskconsumidor; var varitem :: elemento; m :: mensaje; i: i: integer; for fori:=1 to ton do do send( send( productor, m ); ); repeat repeat receive( productor, m ); ); item item := := extraer_msj(m); consumir(item); until untilfalse; end endconsumidor; 105 9. Comunicación por mensajes Mensajes: el modelo cliente-servidor Modelo de comunicación especialmente adecuado para sistemas distribuidos, basado en asociar un proceso servidor al recurso que se desa compartir. Existen dos patrones de comportamiento diferenciados: Servidores: Gestionan un recurso y ofrecen servicios relacionados con el recurso. Reciben peticiones de los clientes, las ejecutan en su nombre y responden a los clientes. Clientes: Envían mensajes de petición a los servidores y esperan respuesta. 106 53

9. Comunicación por mensajes Mensajes: el modelo cliente-servidor Nodo C petición Nodo S C S WWW respuesta CLIENT send(serv, petición); recv(rem, respuesta);...... SERVIDOR repeat repeat recv(serv, petición, ); ); respuesta= trabajar(petición); rem=remite(peticion); send(rem, respuesta, ); ); until until false; false; 107 54